我的问题是:
我有几个Web服务类测试,所有继承的通用服务的方法。 而不是写为每个单元测试,我想我可以通过功能区打破测试套件向下(即,三个组的测试方法,每个依赖于不同的底层DAO方法调用)。
我的建议做的是:
@Mock StateDAO mockedStateDao;
@Mock CountyDAO mockedCountyDao;
@Mock VisitorDAO mockedVisitorDao;
然后调用:
@InjectMocks CountyServiceImpl<County> countyService = new CountyServiceImpl<County>();
@InjectMocks StateServiceImpl<State> stateService = new StateServiceImpl<State>();
@InjectMocks VisitorServiceImpl<Visitor> visitorService = new VisitorServiceImpl<Visitor>();
我如何才能确保每个mockedDAO将被注入到正确的服务? 难道是比较容易自动装配所有三个(而不是使用@InjectMocks)?
我使用Spring,Hibernate和...的Mockito
那么尼古拉斯回答几乎是正确的,但不是猜测只是看的javadoc的InjectMocks ,它包含了更多的细节;)
对我来说,它的怪异有在一个单一的测试这么多的服务,这感觉不对,作为一个单元测试或集成测试。 在单元测试是错误的,因为还有你有太多的合作者,它看起来并不像定向(或固体)对象。 在集成测试,因为你的代码测试与数据库的整合不是嘲笑它,它的怪异。
对于1.9.5快速引用您有:
标记应在其上进行注射的字段。
允许速记模拟和间谍注射。 最大限度地减少重复模拟和间谍注射。 的Mockito将尝试通过构造器注入,setter注入,或财产注射以便并且如下所述仅任一注入嘲笑。 如果有以下策略失败,那么会的Mockito不报告故障; 也就是说,你必须自己提供的依赖。
构造函数注入; 最大的构造选择,那么参数与仅在测试中声明嘲笑解决。
注:如果无法找到参数,则传递null。 如果非mockable类型想要的东西,然后构造器注入将不会发生。 在这种情况下,你将不得不满足依赖自己。
物业setter注入; 模拟考试将首先按类型解决,那么,如果存在多个相同类型的属性,属性名的匹配和模拟名称。
注1:如果你有相同类型(或同一消失)的特性,这是更好的名字了匹配属性的所有@Mock注释字段,否则可能的Mockito感到困惑和注射不会发生。
注2:如果@InjectMocks实例之前未初始化,并有一个无参数的构造函数,那么它将与此构造初始化。
场注入; 模拟考试将首先按类型解决,那么,如果存在多个相同类型的财产,由字段名的匹配和模拟名称。
注1:如果你有相同类型(或同一消失)领域,它更好地命名与匹配字段中的所有批注@Mock领域,否则可能的Mockito感到困惑和注射不会发生。
注2:如果@InjectMocks实例之前未初始化,并有一个无参数的构造函数,那么它将与此构造初始化。
如果您有多个服务和想更换与基于Spring的环境模拟对象的DAO的,我会建议使用Springockito: https://bitbucket.org/kubek2k/springockito/wiki/Home
其中这里也提到: 与注射嘲笑的Mockito成一个Spring bean
然后,您的TestClass可能是这样的:
@RunWith (SpringJUnit4ClassRunner.class)
@ContextConfiguration (loader = SpringockitoContextLoader.class, locations = {"classpath:/org/example/package/applicationContext.xml"})
public class NameOfClassTest {
@Autowired
@ReplaceWithMock
StateDAO mockedStateDao;
@Autowired
@ReplaceWithMock
CountyDAO mockedCountyDao;
@Autowired
@ReplaceWithMock
VisitorDAO mockedVisitorDao;
在您的@测试或@Before了Methode你可以设置你的嘲弄标准方式的Mockito:
Mockito.doReturn(null).when(mockedCountyDao).selectFromDB();
那么,静态方法MockitoAnnotations.initMocks(Object)
被用来引导的全过程。
我不肯定知道它是如何工作的,因为我还没有浏览源代码,但我会实现它是这样的:
- 扫描过
Object
与成员变量的类@Mock
注解。 - 对于每一个,创建该类的一个模拟,并将其设置到该构件。
- 扫描过
Object
与成员变量的类@InjectMocks
注解。 - 扫描类每个找到的构件的会员它可与在(2)中创建的模拟对象(即,这里的字段是一个父类/接口,或同一类中的一个被注入,作为模拟对象声明类),并将其设置到该构件。
没关系,看着online-的InjectMocks注释与@Mock注释对待任何一个领域,是静态的作用域(类宽),所以我真的不能机制保障的嘲笑会去到正确的服务。 这是有些思想实验在功能层面,而不是一流水平试图单元测试。 想我就自动装配这个东西与Spring ...