8

我正在使用 mockito 来模拟单元测试用例,并得到以下异常

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type ConsumerImpl and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
    verify(mock).someMethod();
    verify(mock, times(10)).someMethod();
    verify(mock, atLeastOnce()).someMetenter code herehod();

我的代码是

 MessageConsumer mConsumer = Mockito.mock(MessageConsumer.class);
            String data = "new Message for Testing";
            Message message = new Message(data.getBytes());
            Mockito.when(mConsumer.next(10, TimeUnit.SECONDS)).thenReturn(message);
            StringParserTest parserTest = new StringParserTest();
            ConsumerImpl<String> consumer = new ConsumerImpl<String>(mConsumer, parserTest);
            String mes=Mockito.verify(consumer,VerificationModeFactory.times(3)).consumeMessage(10,TimeUnit.SECONDS);

请有人帮我解决这个问题

提前致谢

SRN

4

2 回答 2

5

好吧,这正是 mockito 所说的,你没有通过一个 mock 来验证!

ConsumerImpl<String> consumer = new ConsumerImpl<String>(mConsumer, parserTest);
String mes=Mockito.verify(consumer,VerificationModeFactory.times(3)).consumeMessage(10,TimeUnit.SECONDS);

另外,如果您验证了一个模拟,为什么要存储您验证的调用结果,因为消费者被模拟了,所以这没有意义。验证是验证对作为单元测试对象协作者的模拟对象的调用。在你的情况下,这不是很清楚。

此外,您从不使用您的模拟mConsumer实例。

您绝对应该将测试分为 3 个阶段,一个用于夹具,一个用于操作,一个用于验证。使用 BDD 术语来实现这一点,它增强了代码的测试人员和未来读者的理解和可读性(并且 Mockito 通过 BDDMockito 在 API 中提供它们)。

由于我并没有真正从您提供的代码中得到代码试图测试的内容,所以我会想象一些事情。因此,例如,您将编写这种代码(使用import static):

// given a consumer
MessageConsumer message_consumer = mock(MessageConsumer.class);
String the_message_data = "new Message for Testing";
given(message_consumer.next(10, SECONDS)).willReturn(new Message(the_message_data.getBytes()));

// when calling the client of the customer (which is the unit that is tested)
new MessageProcessor(message_consumer).processAll();

// then verify that consumeMessage is called 3 times
verify(message_consumer, times(3)).consumeMessage(10, SECONDS);

请记住,Mockito 可以帮助您专注于对象之间的交互——因为它是面向对象编程中最重要的概念——尤其是在被测试者和他的合作者之间,这肯定会被嘲笑。

于 2013-05-29T16:56:56.997 回答
3

通常我们使用@InjectMock 进行模拟,并尝试验证从测试用例方法内部调用的方法。这是一种通常会出现问题的情况。

public class A{
  @Autowired
  Service s

  public void method1(){
    method2();
  }
  public void method2(){
    s.someMethod();
  }
}

public class ATest{

  @InjectMocks
  A a;

  public void testM1(){
    a.method1();
    Mockito.verify(a, Mockito.times(1)).method2();

  }
}

这将始终给出“NoAMockException while Mockito.verify”,而不是我们应该使用以下验证。

public class ATest{
  @InjectMocks
  A a;
  @Mock
  Service s

  public void testM1(){
    a.method1();
    Mockito.verify(s, Mockito.times(1)).someMethod();
  }
}

或者如果我们想要 verify() method2() 那么我们必须 @Mock class A 而不是 @InjectMock

于 2016-01-13T23:13:46.367 回答