我正在尝试编写一个测试模拟调用存储库并调用BloomFilter管理器来检查值。我在测试中模拟以下序列调用时遇到问题:
Mockito.when(bloomFilterManager.getBloomFilter().mightContain(anyString()))
.thenReturn(true);
整个测试:
@RunWith(SpringRunner.class)
@TestConfiguration
public class FooServiceTest {
@Autowired
private BloomFilterManager bloomFilterManager;
@Autowired
private FooService fooService;
@MockBean
private FooRepository fooRepository;
@Before
public void setUp() {
Faker faker = new Faker();
Foo foo = new Foo(
faker.number().randomNumber(),
faker.lorem().word(),
faker.number().randomDigit(),
new BigDecimal(Math.random()),
Foo.PaymentStatus.PAID,
faker.date().between(new Date(), DateUtils.addDays(new Date(), 13))
);
Mockito.when(fooRepository.findOne(anyString()))
.thenReturn(foo);
Mockito.when(bloomFilterManager.getBloomFilter().mightContain(anyString()))
.thenReturn(true);
}
@Test
public void whenValidName_thenEmployeeShouldBeFound() {
String fooId = "100000000000001";
Foo.PaymentStatus actualPaymentStatus = fooService.retrievePaymentStatus(fooId);
assertEquals(Foo.PaymentStatus.PAID, actualPaymentStatus);
}
@TestConfiguration
static class FooServiceTestContextConfiguration {
@Bean
public FooService fooService() {
return new FooService();
}
@Bean
public BloomFilterManager bloomFilterManager() {
return new BloomFilterManager();
}
}
}
BloomFilterManager.class:
@Component
public class BloomFilterManager {
private static final int EXPECTED_INSERTIONS = 500000000;
private static final double FFP = 0.01;
private BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset
()),
EXPECTED_INSERTIONS, FFP);
public void populate(List<Foo> foos) {
foos.stream().map(Foo::getId).forEach(i -> bloomFilter.put(i));
}
public BloomFilter<String> getBloomFilter(){
return bloomFilter;
}
}
在服务中使用BloomFilterManager:
@Service
public class FooService implements IFooService {
@Autowired
private BloomFilterManager bloomFilterManager;
@Autowired
private FooRepository fooRepository;
@Override
public Foo.PaymentStatus retrievePaymentStatus(String fooId) {
if (!bloomFilterManager.getBloomFilter().mightContain(fooId))
return null;
return fooRepository.findOne(fooId).getPaymentStatus();
}
}
我在测试运行期间收到以下错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
at org.learn.unit.FooServiceTest.setUp(FooServiceTest.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
答案 0 :(得分:0)
你的嘲笑是错的。 Mockito遵循一个非常简单的结构。你不能把你的模拟电话联系起来。
Mockito.when(fooRepository.findOne(anyString())) .thenReturn(foo);
需要
Mockito.when(fooRepository).findOne(anyString()) .thenReturn(foo);
Mockito.when(bloomFilterManager.getBloomFilter().mightContain(anyString())) .thenReturn(true); }
需要。
Filter filter = Mockito.mock(Filter.class);
Mockito.when(bloomFilterManager).getBloomFilter().thenReturn(filter);
Mockito.when(filter).mightContain(anyString()).thenReturn(true);