我需要为这个班写一个测试。我需要验证当列表的大小正好是2时,调用modelService.save。是否也可以访问对象productModel?
我不知道从哪里开始。
public class SoldMaterialPrepareInterceptor implements PrepareInterceptor<SoldMaterialModel> {
@Resource
private ModelService modelService;
@Override
public void onPrepare(SoldMaterialModel soldMaterialModel, InterceptorContext interceptorContext) throws InterceptorException {
setSAPSubstance(soldMaterialModel);
}
private void setSAPSubstance(SoldMaterialModel soldMaterialModel) {
ProductModel productModel = soldMaterialModel.getBaseProduct();
Set superCatagoriesList = [....]// gets the list somehow
if (superCatagoriesList.size() == 2) {
productModel.setSupercategories(superCatagoriesList);
modelService.save(productModel);
}
}
}
答案 0 :(得分:1)
modelService字段是私有的并不是问题,它是一个通常需要私有访问修饰符的类字段。您需要检查其save()方法的调用,而该方法又不能是私有的,否则无法从拦截器类中调用它。
对于测试,假设superCatagoriesList(实际上是Set而不是List并且也应该是通用的)从soldMaterialModel参数直接或间接(例如通过productModel)获取其内容,您的任务是编写测试,使用这样的值填充soldMaterialModel,以便superCatagoriesList.size()为2,然后您可以验证modelService.save()方法是否被调用一次,例如
之类的东西Mockito.verify(modelService).save(any(ProductModel.class));
答案 1 :(得分:1)
我发现当最难测试方法时,我正在测试的代码存在设计问题。我建议首先重构一下:将setSAPSubstance移动到SoldMaterialModel类并将其公开。这就是该方法所需要的地方(见feature envy)。当然input
将留在拦截器中,只有在需要时才会调用它。
那么你只需要测试两个公共方法
答案 2 :(得分:1)
您可以向SoldMaterialPrepareInterceptor添加构造函数,该构造函数将ModelService作为参数。然后你可以在测试中使用它。您可能还需要添加无参数构造函数,因为这是您的依赖注入框架如何创建它。更好的是,您可以弄清楚如何配置框架以使用采用ModelService的新构造函数。
public class SoldMaterialPrepareInterceptor {
// Public constructor if needed for dependency injection
public SoldMaterialPrepareInterceptor () { }
// If just used for test use protected or package private
// If used with dependency injection, use public.
protected SoldMaterialPrepareInterceptor(ModelService modelService){
this.modelService = modelService
}
测试类通常与实际类在同一个包中,因此包私有或受保护的范围就足够了。然后测试看起来像这样(假设Mockito和Junit。逻辑上,Spock和其他框架会类似):
ModelService modelService = Mockito.mock(ModelService.class);
SoldMaterialPrepareInterceptor interceptor = new SoldMaterialPrepareInterceptor(modelService);
// setup SoldMaterialModel and InterceptorContext
interceptor.onPrepare(soldMaterialModel, interceptorContext);
Mockito.verify(modelService, Mockito.times(0)).save(soldMaterialModel);