4

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: enter image description here

Kris
  • 562
  • 5
  • 17

3 Answers3

3

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.

Benoit
  • 5,118
  • 2
  • 24
  • 43
  • Fiddled around with the dependencies and imports and once I managed to get everything to match Junit5 it started working. Not really sure which change made it happen, but cheers mate! – Kris Sep 04 '20 at 13:50
1

JUnit 5 uses @ExtendWith(SpringExtension.class) annotation, can you change @RunWith annotation and try again?

0

You should mock the findById call, not the expression chained with orElse:

when(productRepository.findById("001")).thenReturn(product);
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    Correct, but that won't magically make `productRepository` not null. – Benoit Sep 04 '20 at 13:19
  • Tried it and changing it did not make a difference. Think the issue is with repository being null rather than the statement itself. – Kris Sep 04 '20 at 13:21