如何从 jUnit 测试访问 Spring @Service 对象

发布于 2024-12-09 08:08:42 字数 1537 浏览 0 评论 0原文

情况:我有使用 @Service 注释的服务实现类,可以访问属性文件。

@Service("myService")
public class MySystemServiceImpl implements SystemService{

      @Resource
      private Properties appProperties;

}

Properties 对象是通过配置文件配置的。 applicationContext.xml

<util:properties id="appProperties" location="classpath:application.properties"/>

我想测试此实现的一些方法。

问题:如何从测试类访问 MySystemServiceImpl 对象,以便正确初始化属性 appProperties?

public class MySystemServiceImplTest {

    //HOW TO INITIALIZE PROPERLY THROUGH SPRING? 
    MySystemServiceImpl testSubject;

    @Test
    public void methodToTest(){
        Assert.assertNotNull(testSubject.methodToTest());
    }     

}

我无法简单地创建新的 MySystemServiceImpl - 比使用 appProperties 的方法会抛出 NullPointerException 。而且我无法直接在对象中注入属性 - 没有合适的设置方法。

只需在此处放置正确的步骤(感谢@NimChimpsky 的回答):

  1. 我在 test/resources 目录下复制了application.properties

  2. 我将applicationContext.xml复制到test/resources目录下。在应用程序上下文中,我添加新的 bean(应用程序属性的定义已经在这里):

    
    
  3. 我以这种方式修改了测试类:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"/applicationContext.xml"})
    公共类 MySystemServiceImplTest {
    
       @Autowired
       MySystemServiceImpl 测试主题;
    
    }
    
  4. 这就是窍门 - 现在在我的测试类中,功能齐全的对象可用

Situation: I have service implementation class annotated with @Service with access to properties file.

@Service("myService")
public class MySystemServiceImpl implements SystemService{

      @Resource
      private Properties appProperties;

}

Properties object is configured through config-file. applicationContext.xml

<util:properties id="appProperties" location="classpath:application.properties"/>

I want to test some methods of this implementation.

Question:How to access MySystemServiceImpl-object from test class in such way that Properties appProperties will be initialized properly?

public class MySystemServiceImplTest {

    //HOW TO INITIALIZE PROPERLY THROUGH SPRING? 
    MySystemServiceImpl testSubject;

    @Test
    public void methodToTest(){
        Assert.assertNotNull(testSubject.methodToTest());
    }     

}

I can't simple create new MySystemServiceImpl - than methods that use appProperties throws NullPointerException. And I can't directly inject properties in the object - there is no appropriate setter-method.

Just put correct steps here (thanks to @NimChimpsky for answer):

  1. I copied application.properties under test/resources dir.

  2. I copied applicationContext.xml under test/resources dir. In application context I add new bean (definition of application properties is already here):

    <bean id="testSubject" class="com.package.MySystemServiceImpl">
    
  3. I modified test class in such way:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"/applicationContext.xml"})
    public class MySystemServiceImplTest {
    
       @Autowired
       MySystemServiceImpl testSubject;
    
    }
    
  4. And this make the trick - now in my test class fully functional object is available

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遇到 2024-12-16 08:08:42

或者,为了进行集成测试,我这样做。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext-test.xml"})
@Transactional
public class MyTest {

    @Resource(name="myService")
    public IMyService myService;

然后像平常一样使用该服务。将应用程序上下文添加到您的 test/resources 目录

Alternatively, to do an integration test I do this.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext-test.xml"})
@Transactional
public class MyTest {

    @Resource(name="myService")
    public IMyService myService;

Then use the service as you would normally. Add the app context to your test/resources directory

温柔戏命师 2024-12-16 08:08:42

只需使用它的构造函数:

MySystemServiceImpl testSubject = new MySystemServiceImpl();

这是一个单元测试。单元测试测试一个与其他类和基础设施隔离的类。

如果您的类依赖于其他接口,请模拟这些接口并使用这些模拟作为参数创建对象。这就是依赖注入的全部要点:能够在对象内注入其他模拟实现,以便轻松测试该对象。

编辑:

您应该为属性对象提供一个setter,以便能够为每个单元测试注入您想要的属性。注入的属性可能包含标称值、极值或不正确的值,具体取决于您要测试的内容。字段注入很实用,但不太适合单元测试。当使用单元测试时,应该首选构造函数或设置器注入,因为依赖注入的主要目标正是能够在单元测试中注入模拟或特定依赖项。

Just use its constructor :

MySystemServiceImpl testSubject = new MySystemServiceImpl();

This is a unit test. A unit test tests a class in isolation from the other classes and from the infrastructure.

If your class has dependencies over other interfaces, mock those interfaces and create the object with these mocks as argument. That's the whole point of dependency injection : being able to inject other, mock implementations inside an object in order to test this object easily.

EDIT:

You should provide a setter for your properties object, in order to be able to inject the properties you want for each of the unit tests. The injected properties could contain nominal values, extreme values, or incorrect values depending on what you want to test. Field injection is practical, but doesn't fit well with unit-testing. Constructor or setter injection should be preferred when unit-testing is used, because the main goal of dependency injection is precisely to be able to inject mock or specific dependencies in unit tests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文