开发者

How to access Spring @Service object from jUnit test

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());
    }     

}
开发者_Go百科

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


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜