Mockito.verify(Object,VerificationMode.atleast(2))时出现NoAMockException

时间:2013-05-29 16:02:50

标签: java testng mockito junit-ee

我正在使用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

2 个答案:

答案 0 :(得分:4)

嗯,这正是mockito所说的,你没有通过模拟验证!

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

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

此外,您永远不会使用模拟mConsumer实例。

你绝对应该将你的测试分为三个阶段,一个用于夹具,一个用于操作,一个用于验证。使用BDD术语来实现这一点,它增强了测试人员和未来读者对此代码的理解和可读性(And 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可以帮助你专注于对象之间的交互 ​​- 因为它是面向对象编程最重要的概念 - 尤其是被测试者和他的合作者之间肯定会被嘲笑。

答案 1 :(得分:1)

通常我们使用@InjectMock进行模拟,我们尝试验证从测试用例方法内部调用的方法。 这是一个通常会产生问题的方案。

public class A{
  @Autowired
  Service s

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

public class ATest{

  @InjectMocks
  A a;

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

  }
}

当Mockito.verify&#34;这将永远给出&#34; NoAMockException。 而不是我们应该使用以下验证。

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

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

或者如果我们想验证()method2() 那么我们必须使用@Mock类而不是@InjectMock