如何从 jUnit 测试访问 Spring @Service 对象
情况:我有使用 @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 的回答):
我在 test/resources 目录下复制了application.properties。
我将applicationContext.xml复制到test/resources目录下。在应用程序上下文中,我添加新的 bean(应用程序属性的定义已经在这里):
我以这种方式修改了测试类:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/applicationContext.xml"}) 公共类 MySystemServiceImplTest { @Autowired MySystemServiceImpl 测试主题; }
这就是窍门 - 现在在我的测试类中,功能齐全的对象可用
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):
I copied application.properties under test/resources dir.
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">
I modified test class in such way:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/applicationContext.xml"}) public class MySystemServiceImplTest { @Autowired MySystemServiceImpl testSubject; }
And this make the trick - now in my test class fully functional object is available
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
或者,为了进行集成测试,我这样做。
然后像平常一样使用该服务。将应用程序上下文添加到您的 test/resources 目录
Alternatively, to do an integration test I do this.
Then use the service as you would normally. Add the app context to your test/resources directory
只需使用它的构造函数:
这是一个单元测试。单元测试测试一个与其他类和基础设施隔离的类。
如果您的类依赖于其他接口,请模拟这些接口并使用这些模拟作为参数创建对象。这就是依赖注入的全部要点:能够在对象内注入其他模拟实现,以便轻松测试该对象。
编辑:
您应该为属性对象提供一个setter,以便能够为每个单元测试注入您想要的属性。注入的属性可能包含标称值、极值或不正确的值,具体取决于您要测试的内容。字段注入很实用,但不太适合单元测试。当使用单元测试时,应该首选构造函数或设置器注入,因为依赖注入的主要目标正是能够在单元测试中注入模拟或特定依赖项。
Just use its constructor :
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.