简体   繁体   中英

Configuring state of mocked object for different scenarios

I've a DAO and a service class. In the service class CapService , I've @Autowired a reference of DAO class CapDAO . The CapDAO class has a private instance field of type int , that has it's value injected from a properties file using @Value annotation.

class CapDAO {
    @Value("${someProperty}")
    private int expiryTime;
}

class CapService {
    @Autowired
    private CapDAO capDAO;
}

There is a method - retrieveCap() in the CapDAO class, which retrieves the caps from the database, based on the expiryTime . That method is invoked from another method in CapService class.

The CapService class uses the list returned from DAO method to create another object wrapping that list. And finally it returns that data structure.

Now, I'm testing a scenario using Mockito framework. I've two scenarios. In both of them, I want to invoke method of CapService class, which will get me the object. The list retrieved form database, will depend upon the value of expiryTime in the CapDAO class. And so will the content of the object returned by CapService class method.

In test, I'm invoking the method in Service class, and checking the value returned. Since DAO is reading expiryTime from properties file, both the test scenarios cannot pass with the same configured value. I've to have two differently configured DAO instance to be injected into Service class.

So, my question is - is there any way I can configure the expiryTime in CapDAO class, to create two different instance, or may be in a single instance only, and inject those in CapService based on scenario? No I don't have any setter for expiryTime . Yes, I knwo I can use reflection, but I would like to keep that as my last resort.

Short answer

reflection is easiest possibility, you can simply use ReflectionTestUtil . Note: If you have an interface which CapDAO implements, you need also AopUtils

Long answer

If you don't wanna use reflection, you need separate your context and test to get this work:

// context1.xml
<context:property-placeholder location="classpath:test1.properties"/>
// context2.xml
<context:property-placeholder location="classpath:test2.properties"/>

Then you can define someProperty with some other value in the properties.

personally i will recommend reflection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM