问题描述
我有一个正在为其编写常规测试用例的类。此类具有构造函数自动装配,并调用另一个方法来初始化字段。
@Service
public class ServiceA {
private final PrincipalDao principalDao;
@Autowired
public ServiceA(final PrincipalDao principalDao){
this.principalDao=principalDao;
this.serviceMap = getMap();
}
private Map<> getMap() {
final List<ClassA> classAList = principalDao.findAll(); //this line returns null
}
}
此行final List<ClassA> classAList = principalDao.findAll();
返回null
,我无法像下面这样以常规方式对其进行模拟:
principalDao.findAll() >> list
解决方法
在没有看到您进行单元测试的情况下,很难说出问题是什么,但是有时我遇到的一个普遍误解是模拟的时机。
这是一个示例代码,详细说明了我的意思。由于您的问题中缺少部分代码,因此请假设其中的某些部分,但是我确定它可以解释我的观点,并希望能帮助您找到答案:
服务类别:
@Service
public class ServiceA{
private final PrincipalDao principalDao;
private final Map<String,String> serviceMap;
@Autowired
public ServiceA(final PrincipalDao principalDao){
this.principalDao = principalDao;
this.serviceMap = getMap();
}
private Map<String,String> getMap(){
final HashMap<String,String> stringStringHashMap = new HashMap<String,String>();
stringStringHashMap.put("hello",principalDao.khello());
return stringStringHashMap;
}
public String printServiceMap() {
return serviceMap.get("hello");
}
}
class ServiceATest extends Specification {
def "some test"() {
given:
PrincipalDao principalDao = Mock()
principalDao.khello() >> "khello" // this is the key here. Mocking is happening before instantiation of ServiceA
ServiceA someService = new ServiceA(principalDao)
expect:
"khello" == someService.printServiceMap()
}
}
此单元测试成功通过。这里的重点是嘲弄的时间。 principalDao.khello() >> "khello"
发生在new ServiceA(principalDao)
之前。
如果您不需要修改每个单元测试的serviceMap,也可以执行此操作,因此您不必为每个单元测试定义它:
class ServiceATest extends Specification {
@Shared
PrincipalDao principalDao = Mock()
ServiceA someService = new ServiceA(principalDao)
def setupSpec() {
principalDao.khello() >> "khello"
}
def "some test"() {
expect:
"khello" == someService.printServiceMap()
}
}