【发布时间】:2013-11-19 01:34:25
【问题描述】:
问题
我正在使用测试驱动开发,但无法让我的测试很好地定义我的代码。我的问题的一个简单示例如下。
我有MyObject,我想从中调用属于OtherObject 的methodA() 或methodB(),具体取决于MyObject 在它自己的callMethod(int) 中接收的参数。
预期代码(和所需功能)
这本质上是我希望代码执行的操作 - 但我想先对其进行测试:
public class MyObject {
private final OtherObject otherObject;
public MyObject(OtherObject otherObject) {
this.otherObject = otherObject;
}
public void callMethod(int i) {
switch (i) {
case 0:
otherObject.methodA();
break;
case 1:
otherObject.methodB();
break;
}
}
}
先写测试
为了实现这一点,我首先编写了一个测试 - 检查在调用 callMethod(0) 时是否调用了 methodA()。我使用 JUnit 和 Mockito。
public class MyObjectTest {
private final OtherObject mockOtherObject = mock(OtherObject.class);
private final MyObject myObject = new MyObject(mockOtherObject);
@Test
public void callsMethodA_WhenArgumentIs0() {
myObject.callMethod(0);
verify(mockOtherObject).methodA();
}
}
我通过像这样实现MyObject 的方法来创建消除错误并使测试通过所需的类/方法:
public void callMethod(int i) {
otherObject.methodA();
}
接下来测试另一个选项 - 调用 callMethod(1)
@Test
public void callsMethodB_WhenArgumentIs1() {
myObject.callMethod(1);
verify(mockOtherObject).methodB();
}
我得到了一个最终解决方案:
public void callMethod(int i) {
otherObject.methodA();
otherObject.methodB();
}
问题
这可行,但显然不是我想要的。如何使用测试进行到我想要的代码?在这里,我测试了我想要的行为。我能想到的唯一解决方案是为我不希望看到的行为编写更多测试。
在这个例子中,可以再编写 2 个测试来检查另一个方法是否没有被调用,但在一般情况下,这样做肯定是一个更大的问题。当有更多选项时,根据情况不同,方法和调用多少不同的方法会更复杂。
假设在我的示例中有 3 种方法 - 我是否必须编写 3 个测试来检查是否调用了正确的方法 - 如果我要检查 3 种情况中的每一种都没有调用其他 2 种方法,那么还有 6 种方法? (无论您是否尝试在每个测试中坚持一个断言,您仍然必须全部编写。)
看起来测试的数量会影响代码有多少选项。
另一种选择是只编写 if 或 switch 语句,但从技术上讲,它不会由测试驱动。
【问题讨论】:
标签: java unit-testing junit tdd