如何从jUnit test访问Spring @Service对象

时间:2011-10-11 09:31:17

标签: java spring junit

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

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

      @Resource
      private Properties appProperties;

}

通过config-file配置属性对象。的的applicationContext.xml

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

我想测试一下这种实现的方法。

问题:如何从测试类中访问MySystemServiceImpl-object,以便正确初始化Properties appProperties?

public class MySystemServiceImplTest {

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

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

}

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

在这里添加正确的步骤(感谢@NimChimpsky的回答):

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

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

    <bean id="testSubject" class="com.package.MySystemServiceImpl">
    
  3. 我以这种方式修改了测试类:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"/applicationContext.xml"})
    public class MySystemServiceImplTest {
    
       @Autowired
       MySystemServiceImpl testSubject;
    
    }
    
  4. 这就是诀窍 - 现在在我的测试类中可以使用全功能对象

2 个答案:

答案 0 :(得分:7)

或者,要进行集成测试,我会这样做。

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

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

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

答案 1 :(得分:1)

只需使用其构造函数:

MySystemServiceImpl testSubject = new MySystemServiceImpl();

这是一项单元测试。单元测试与其他类和基础结构隔离地测试类。

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

修改

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