我们最终将我们的单元测试代码库从JUnit 3迁移到JUnit 4.我们也大量使用JMock 2.
使用JUnit 3,JMock为您的测试提供了一个有用的基类(MockObjectTestCase),它本身就是Junit的TestCase的子类,它处理有关模拟框架的各种内务管理职责。它使测试课的生活变得非常简单。
现在有了JUnit4,JMock没有提供这样的支持。您的测试类必须手动创建Mockery对象,它必须记住使用正确的测试运行器注释,并且必须将所有与模拟相关的操作委托给mockery。简而言之,它对测试类的责任远远超过JUnit 3测试所需的责任。
现在我很欣赏JUnit4的魅力在于没有必要对某些内容进行子类化,但是这种JMock情况似乎是向后退一步,并且使得从3到4的移植工作相当多,而不是必要的。
我错过了什么吗?有没有一种很好的方法来编写我的JUnit4 / Jmock2测试类而无需手动将所有管道添加到每个类?当然,我可以编写自己的支持基类,但是从JMock2 API看来这是一个明显的遗漏,我不得不怀疑我是否错过了这一点。
编辑:这是可选支持类的源代码:
@RunWith(JMock.class)
public class JMockSupport {
protected final Mockery mockery = new Mockery();
protected void checking(ExpectationBuilder expectations) {
mockery.checking(expectations);
}
protected <T> T mock(Class<T> typeToMock) {
return mockery.mock(typeToMock);
}
protected <T> T mock(Class<T> typeToMock, String name) {
return mockery.mock(typeToMock, name);
}
protected Sequence sequence(String name) {
return mockery.sequence(name);
}
protected void setDefaultResultForType(Class<?> type, Object result) {
mockery.setDefaultResultForType(type, result);
}
protected void setImposteriser(Imposteriser imposteriser) {
mockery.setImposteriser(imposteriser);
}
protected void setNamingScheme(MockObjectNamingScheme namingScheme) {
mockery.setNamingScheme(namingScheme);
}
protected States states(String name) {
return mockery.states(name);
}
}
这包含JUnit3 MockObjectTestCase类定义的所有方法,这些方法只是回应嘲弄。 @RunWith注释也存在,以避免忘记将其添加到测试类中。
答案 0 :(得分:2)
我也完成了这次迁移,这很痛苦。我可以理解为什么他们已经对基类机制进行了分区 - 我试图用支持Spring JUnit的基类来处理JMock基类,而这显然不起作用。
一旦我开始进行迁移,我发现'优化'的一个领域是创建适当的Expectation基类,在模拟对象上封装常见操作,而不是为每个测试创建一个新的Expectation对象(和实例)。这会让你有点悲伤。
答案 1 :(得分:1)
没有。没有这样的支持。
JMock 1中的测试基类导致了很多问题,因为你只能扩展一个类,所以人们不能将JMock与其他也定义基类的测试框架一起使用。这就是为什么我们在JMock2中使用委托而不是继承。
也就是说,只要您使用@RunWith(JMock.class)注释您的类,您就可以使用JMock2的JUnit3支持库中的MockObjectTestCase类。但我没试过。
有一个“自动模拟”JUnit4运行器的请求,它将通过自动反射为您创建上下文和模拟对象。有些人喜欢这样,有些人真的不喜欢它。如果您需要此功能,请vote for the issue in the JMock JIRA。
答案 2 :(得分:1)
拥有基类也存在问题。在以前的版本中,我试图组合来自不同测试框架的基类。这就是为什么我们去构造而不是继承。看看我们可以用新的@Rule结构做些什么会很有趣。