Issue
I have created a basic Rest API with a Controller, Service and Repository layer. I am now trying to write a unit test for the Service layer method that finds product by the product id. However, when I run the test it throws a NullPointerException in the line where I am trying to mock the repository findById() method.
The getProductById() method in the service layer is as follows:
public Product getProductById(String id){ return productRepository.findById(id).orElse(null); }
My test class for the service layer:
package com.product.Services;
import com.product.Entities.Product;
import com.product.Repositories.ProductRepository;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
class ProductServiceTest {
@InjectMocks
ProductService productService;
@Mock
ProductRepository productRepository;
@Test
void getProductById() throws Exception {
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
when(productRepository.findById("001").orElse(null)).thenReturn(product);
assertEquals(product,productService.getProductById("001"));
}
}
Attaching a picture of what the debugger shows:
Solution
The problem is that 2 different versions of JUnit are used here:
org.junit.jupiter.api.Test
is from JUnit5, while
org.junit.runner.RunWith
is from JUnit4.
RunWith
does not exist anymore in JUnit5.
In this specific case, I would use JUnit4 - i.e. use the annotation org.junit.Test
(instead of org.junit.jupiter.api.Test
) to annotate your test.
How to use Mockito with JUnit5 provides other valid solutions.
Answered By - Benoit