Java 使用Mockito测试抽象类不会得到预期的结果
我有一个类似于下面的类结构Java 使用Mockito测试抽象类不会得到预期的结果,java,mockito,testng,abstract-class,Java,Mockito,Testng,Abstract Class,我有一个类似于下面的类结构 public abstract class AbstractStep { private final Range RANGE; AbstractStep(AbstractStepBuilder builder) { RANGE = builder.range; } public abstract static class AbstractStepBuilder { Ran
public abstract class AbstractStep {
private final Range RANGE;
AbstractStep(AbstractStepBuilder builder) {
RANGE = builder.range;
}
public abstract static class AbstractStepBuilder {
Range range;
public AbstractStepBuilder setRange(int start, end end) {
this.range = new Range(start, end);
return self();
}
abstract AbstractStepBuilder self();
}
public static class Range() {
private final int START;
private final int END;
private Range(int start, int end) {
if(start < 0 || end < 0 || start >= end)
throw new IllegalArgumentException();
START = start;
END = end;
}
}
}
这个测试失败了。我还尝试用Mockito.mock(AbstractStepBuilder.class),Mockito.mock(AbstractStepBuilder.class,Mockito.CALLS\u REAL\u METHODS)替换Mockito.mock(AbstractStepBuilder.class)
请注意,如果我将CodeRange
作为自己的外部类,则此测试通过,因此我不相信它可能是测试本身
为什么这个测试失败了,有没有可能不用在测试中使用一个具体的类来修复它?您正在对一个模拟调用一个方法,该方法在您告诉它之前不会抛出异常。您永远不会模拟要测试的类
如果要测试实际的类,需要创建StepBuilder的子类,创建一个实例并进行测试
我认为您还可以创建一个spy(通过Mockito.spy(AbstractStepBuilder.class)
)来避免仅为测试创建一个子类。您正在对一个mock调用一个方法,该方法在您告诉它之前不会抛出异常。您永远不会模拟要测试的类
如果要测试实际的类,需要创建StepBuilder的子类,创建一个实例并进行测试
我认为你也可以创建一个间谍(通过Mockito.spy(AbstractStepBuilder.class)
)来避免仅仅为了测试而创建一个子类。你根本不调用AbstractStepBuilder#setRange你会得到什么错误?@kofemann Fixed,很抱歉,由于从更复杂的project@ThomasMartinRangeTest
中的测试失败“我们可以修复它,而不必在测试中使用具体类吗?”具体地说是否,因为您无法在具体类上调用实例方法。它必须是具体的。在测试范围中创建一个最小的子类看起来是一种正确的方法。您根本不调用AbstractStepBuilder#setRange会出现什么错误?@kofemann修复了,很抱歉,由于从更复杂的project@ThomasMartin范围测试中的测试失败“我们可以在不必在测试中使用具体类的情况下修复它吗?”?“具体地说,没有,因为您无法在具体类上调用实例方法。它必须是具体的。在测试范围内创建一个最小的子类看起来是一个正确的方法。@davidxxx是的,但我懒得在文档中找到反对它的部分:P另外,为测试创建一个专门的子类对我来说也有一种代码味道。所以我想这是两害相权取其轻的情况。为测试创建一个子类也不一定是今天最好的事情,我同意:)可能它们之间有一条路径:)@davidxxx可能定义一个子类,然后创建一个间谍…;)这不是两个世界中最糟糕的吗?不,我认为你的第一个想法很好。通常我不会尝试测试抽象类,因为它是抽象的。如果我真的需要这样做,例如,因为我向其他客户机公开了一个类,那么在测试范围内创建一个子类并不是一件坏事。不管你对第一点投什么票:)@davidxxx是的,那是个笑话。@davidxxx是的,但我懒得在文档中找到反对它的部分:P另外,专门为测试创建子类对我来说也有代码味道。所以我想这是两害相权取其轻的情况。为测试创建一个子类也不一定是今天最好的事情,我同意:)可能它们之间有一条路径:)@davidxxx可能定义一个子类,然后创建一个间谍…;)这不是两个世界中最糟糕的吗?不,我认为你的第一个想法很好。通常我不会尝试测试抽象类,因为它是抽象的。如果我真的需要这样做,例如,因为我向其他客户机公开了一个类,那么在测试范围内创建一个子类并不是一件坏事。不管你对第一点投什么票:)@davidxxx是的,那是个笑话。
final class RangeTest {
AbstractStepBuilder builder;
@BeforeSuite
void setup() {
builder = Mockito.mock(AbstractStepBuilder.class);
Mockito.when(builder.self()).thenReturn(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
final void testCreatingRangeWithNegativeStart() {
builder.setRange(-1, 2);
}
}