Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Mockito.verify()?

I write jUnit test cases for 3 purposes:

  1. To ensure that my code satisfies all of the required functionality, under all (or most of) the input combinations/values.
  2. To ensure that I can change the implementation, and rely on JUnit test cases to tell me that all my functionality is still satisfied.
  3. As a documentation of all the use cases my code handles, and act as a spec for refactoring - should the code ever need to be rewritten. (Refactor the code, and if my jUnit tests fail - you probably missed some use case).

I do not understand why or when Mockito.verify() should be used. When I see verify() being called, it is telling me that my jUnit is becoming aware of the implementation. (Thus changing my implementation would break my jUnits, even though my functionality was unaffected).

I'm looking for:

  1. What should be the guidelines for appropriate usage of Mockito.verify()?

  2. Is it fundamentally correct for jUnits to be aware of, or tightly coupled to, the implementation of the class under test?

like image 835
Russell Avatar asked Sep 21 '12 23:09

Russell


People also ask

What is verify in unit test?

Asserts are used to validate that properties of your system under test have been set correctly, whereas Verify is used to ensure that any dependencies that your system under test takes in have been called correctly.

Does Mockito verify use equals?

Internally Mockito uses Point class's equals() method to compare object that has been passed to the method as an argument with object configured as expected in verify() method. If equals() is not overridden then java. lang.

Which method in Mockito verifies that no interaction has happened with a mock in Java?

Mockito verifyZeroInteractions() method It verifies that no interaction has occurred on the given mocks. It also detects the invocations that have occurred before the test method, for example, in setup(), @Before method or the constructor.


1 Answers

If the contract of class A includes the fact that it calls method B of an object of type C, then you should test this by making a mock of type C, and verifying that method B has been called.

This implies that the contract of class A has sufficient detail that it talks about type C (which might be an interface or a class). So yes, we're talking about a level of specification that goes beyond just "system requirements", and goes some way to describing implementation.

This is normal for unit tests. When you are unit testing, you want to ensure that each unit is doing the "right thing", and that will usually include its interactions with other units. "Units" here might mean classes, or larger subsets of your application.

Update:

I feel that this doesn't apply just to verification, but to stubbing as well. As soon as you stub a method of a collaborator class, your unit test has become, in some sense, dependent on implementation. It's kind of in the nature of unit tests to be so. Since Mockito is as much about stubbing as it is about verification, the fact that you're using Mockito at all implies that you're going to run across this kind of dependency.

In my experience, if I change the implementation of a class, I often have to change the implementation of its unit tests to match. Typically, though, I won't have to change the inventory of what unit tests there are for the class; unless of course, the reason for the change was the existence of a condition that I failed to test earlier.

So this is what unit tests are about. A test that doesn't suffer from this kind of dependency on the way collaborator classes are used is really a sub-system test or an integration test. Of course, these are frequently written with JUnit too, and frequently involve the use of mocking. In my opinion, "JUnit" is a terrible name, for a product that lets us produce all different types of test.

like image 80
Dawood ibn Kareem Avatar answered Oct 17 '22 10:10

Dawood ibn Kareem