【发布时间】:2015-06-05 21:23:21
【问题描述】:
我正在尝试使用 jmocks 和 junit 编写单元测试。 (我的项目使用核心 java-无框架-)当依赖项在无 arg 构造函数中初始化时,我无法通过模拟外部依赖项为我的某些类编写单元测试。
由于我无法提供实际代码,试图通过一个例子来解释这个场景
public interface Apple {
String variety();
}
实施。
public class MalgovaApple implements Apple {
@Override
public String variety() {
return "Malgova";
}
}
要测试的类
public class VarietyChecker {
private Apple apple;
VarietyChecker(){
this.apple = new MalgovaApple();
// instead of new, a factory method is used in actual application
}
public String printAppleVariety(){
String variety = apple.variety();
if(variety.length() < 3){
System.out.println("Donot use Code names- Use complete names");
return "bad";
}
return "good";
}
}
使用 jmock 进行 Junit 测试
public class VarietyCheckerUnitTest{
Mockery context = new JUnit4Mockery();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void test_VarietyChecker() throws Exception{
final Apple mockapple = context.mock(Apple.class);
VarietyChecker printer = new VarietyChecker();
context.checking(new Expectations(){{
oneOf(mockapple).variety();will(returnValue("as"));
}});
String varietyNameValid = printer.printAppleVariety();
assertEquals("bad",varietyNameValid);
} }
此测试失败 - 模拟不起作用,值“as”未注入,测试类使用 MalgovaApple 执行...
现在,如果我们将以下构造函数添加到 VarietyChecker 并使用它测试用例 - 它会给出预期的输出...
public VarietyChecker(Apple apple) {
super();
this.apple = apple;
}
并在单元测试中创建测试类对象,如 VarietyChecker 打印机 = new VarietyChecker(mockapple);
仅仅为了测试而公开一个新的构造函数并不是一个好主意。毕竟都说不能单独修改测试代码,不止这些,恐怕我们已经写了“一些”(数量)代码了……
我是否遗漏了 junit 或 jmock 中的某些内容,即使在无参数构造函数的情况下也可以使模拟工作。或者这是简单 junit 和 jmocks 的限制,我应该迁移到像 Jmockit /PowerMock
这样强大的东西吗【问题讨论】:
-
如果您必须更改代码才能对其进行测试,那么代码编写得不好。对其他事物的依赖太多,无法正常工作。也就是说,我不能说将批发迁移到 Mockito 会解决您的问题;这是其中之一,我敢肯定。
-
@Makoto 我反对你的第一句话。这是单元测试顽固分子提出的口头禅,不鼓励对测试的价值进行诚实的评估。我以前自己也相信,但那是在我意识到没有银弹之前。现实情况是,编写好的测试并理解它们给你的反馈与编写好的代码一样是一种技能和艺术,而且这种技能也很难掌握。
标签: java unit-testing junit4 jmockit jmock