class SomeClass {
private final Supplier<? extends B> bFactory;
public SomeClass(final Supplier<? extends B> bFactory) {
this.bFactory = bFactory;
}
// Production code can use the parameterless constructor to get the old behavior
// But this is mostly to help with migration, real code should use the parameterized constructor too
public SomeClass() {
this(B::new);
}
public void doSomeThing() {
B b = this.bFactory.get();
A a = b.foo();
a.foo();
}
}
现在你可以注入一个提供者,它在你的测试中提供你的类的一个模拟示例:
@Test
void test() {
final A aMock = mock(A.class);
when(aMock.foo()).thenAnswer(a -> /* ... */);
final B bMock = mock(B.class);
when(bMock.foo()).thenReturn(aMock);
final SomeClass someClass = new SomeClass(() -> bMock);
assertDoesNotThrow( () -> someClass.doSomeThing() );
}
3条答案
按热度按时间hs1ihplo1#
由于您的代码创建了
B
类的新示例,因此不可能模拟所述对象的行为。SomeClass
和B
紧密耦合,并且SomeClass
依赖于B
的具体实现。你可以重构你的类使之成为可测试的。要做到这一点,允许你的类的消费者注入如何创建
B
的行为。一个可能的解决方案是:现在你可以注入一个提供者,它在你的测试中提供你的类的一个模拟示例:
请注意,通常认为让模拟返回模拟是不好的做法。这样的设置会使您的测试脆弱、不必要的复杂,并且与实现耦合。
在Why is mocking static method with Mockito not working in my case?后找到详尽的问题陈述和替代解决方案
xn1cxnb42#
试试这个@模拟B b;
如果b.foo。
jecbmhm33#
必须调用openMocks(this)方法来初始化带注解的对象。
请参阅Annotation Type Mock。
因此,测试类应如下所示: