如何模拟几个序列调用

时间:2018-02-22 15:22:33

标签: spring-boot mockito bloom-filter

我正在尝试编写一个测试模拟调用存储库并调用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)

1 个答案:

答案 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);