The tutorial Junit Mockito Verify method will show you how you verify whether your method has been executed at least once or not. When you write Junit test case for void method then you cannot return anything from your actual method test but at the same time you also don’t know whether your actual method has been executed or not. Therefore you need some mechanism by which you make sure that your method has been executed at least once. So Junit’s Verify method comes into rescue. This Junit Mockito Verify example will also shows how to resolve the issue – Argument passed to verify() is of type <instance name of class> and is not a mock!, which occurs during use of Mockito’s Verify method without spying the object.

You can also check the tutorial Junit test case on Java’s thread where I have used Verify method to check whether the method executed at least once. You may also like to read other Junit tutorials.

In this Junit Mockito Verify example I will show you how you can apply Mockito’s Verify method while you are writing Junit test case on Spring Service class. It is not necessary that you have to write test case for Spring Service class but you can write for any Java class.

Prerequisites

Knowledge on Spring, Java, Junit, Mockito framework
Junit and Mockito framework dependencies

Please read below in order to understand the concept:

Suppose you have a Spring Service class as shown below and you want to write Junit test case for this class. Please don’t try to run the below code you won’t be able to execute it. This is just for explanation purpose.

Consider you have a Spring Data JPA repository called UserRepository that is used to perform basic CRUD operations on User data.

Assume user is an entity class and UserDto is DTO class and ExternalService is a service that fetches user data from external service.

In the below class we have define a void method that should save the user data into underlying database.

@Service
public class UserService {
                
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private ExternalService externalService;
	
	public void saveUser(String userId) {
		UserDto userDto = externalService.getUser(userId);
		User user = convertToUserEntity(userDto);
		userRepository.save(user);
	}
                
}

Now we would write a Junit class for the above service class and see how to user Junit Mockito Verify method.

Write below Junit class:

Here in the below Junit class we are mocking everything except the class for which we will create Junit test case.

We are running the class with MockitoJUnitRunner class.

We are injecting all mock service or repository into the UserService class for which we are writing test case.

We need to initialize all mock objects, so we do it through init() method before running any test case.

In this class we return mock object for any external service call or database operation. Then we call the actual service method saveUser() of userService class.

Then we finally verify whether the saveUser method has been executed at least once using Mockito’s Verify method.

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
                
	@Mock
	private ExternalService externalService;
	
	@Mock
	private UserRepository userRepository;
	
	@InjectMocks
	private UserService userService = new UserService();
	
	@Before
	public void init() {
					MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void testSaveUser() throws Exception {
		Mockito.when(externalService.getUser(Mockito.anyObject())).thenReturn(new userDto());
		Mockito.when(userRepository.save(Mockito.anyList())).thenReturn(new ArrayList<>());
		userService.saveUser("548791");
		Mockito.verify(userService, Mockito.times(1)).saveUser("548791");
	}
                
}

Testing the Junit class

Now in this current condition, if you run the Junit test class you will get an exception similar to the following:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type userService 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()).someMethod();
                at com.jeejava.UserServiceTest.testStoreExcelFileDataToDatabase(UserServiceTest.java:27)
                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.InvokeMethod.evaluate(InvokeMethod.java:17)
                at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
                at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
                at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
                at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
                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.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
                at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
                at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
                at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
                at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Why we got the above exception?

We got this exception because userService is not a mock, and therefore you cannot record behavior on it. You need to use Mockito.Spy() or @Spy annotation to spy the userService object so that you only record the behaviour of saveUser() method and execute the actual code for saveUser() method.

Updating Junit class

Now update the following line of code

@InjectMocks
private UserService userService = new UserService();

by

@Spy
@InjectMocks
private UserService userService = new UserService();

Testing the Junit class

Now run the Junit class again, you should not see any exception.

Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *