0

I am trying to mock my AddressService using JUnit with Mockito, the class under test looks a bit like this;

    @Autowired
    private AddressDataManager addressDataManager;

    /**
     * Delegate AddressDataManager to add an individual Address object
     * @param address
     * @return Address object
     */
    public Address addAddress(Address address) {
        return this.addressDataManager.addAddress(address);
    }

Which then calls a JPA repository;

     /**
     * Create a new Address
     * 
     * @param address
     * @return JSON representation of an Address object
     */
    public Address addAddress(Address address) {
        addressRepo.save(address);
        return address;
    }

This issue is that I am getting a NullPointerException, when trying to create an Address result object using addAddress, which invokes the save() repository method call in my addressService class. It seems to be not returning the address object when I send an address object to it.

I have tried to;

  • create a constructor with the AddressRepository and AddressDataManager in AddressManager
  • Strangely, it works fine when I remove the @Mock addressRepository and AddressDataManager from the class and instead use AddressManager as the @Mock (instead of @InjectMocks). But I'm not sure that is the correct approach as some methods in AddressManager directly use the AddressRepository, so it should also create a NPE.

My Mockito test code:

@RunWith(MockitoJUnitRunner.class) 
public class AddressServiceTest {

    @Mock
    private AddressRepository addressRepo;

    @Mock
    private AddressDataManager addressDataManager;

    @InjectMocks
    private AddressManager addressService;

    public Address createTestData() {
        /** Create an Address **/
        Address mockAddress = new Address();
        /** Set fields **/
        mockAddress.setId((long) 1);
        mockAddress.setStreet("A Street");
        // ...
        return mockAddress;
    }

    /**
     * Test the addressService addAddress and addessRepo save method
     */
    @Test
    public void addAddressTest() {
        Address mockAddress = createTestData();
        /** Test the return type of save is indeed `Address` **/
        when(addressRepo.save(mockAddress)).thenReturn(mockAddress);    
        /** Create a returning result object to test addAddress method return **/
        Address addResult = addressService.addAddress(mockAddress); // NullPointerException here
        /** Check values are equal to address object **/
        assertEquals(Long.valueOf(1), addResult.getId());
        assertEquals("A Street", addResult.getStreet());
        // ...
        /** Verify that addressRepo save was called once using Mockito **/
        verify(addressRepo, times(1)).save(addResult); 
        verify(addressService, times(1)).addAddress(addResult);
    }

I feel like I am close, maybe I have the wrong tag over the wrong class? As I said, it worked well when I just used it like so;

@Mock
private AddressManager addressService;

/** Test the return type of addAddress is indeed `Address` **/
when(addressService.addAddress(mockAddress)).thenReturn(mockAddress);   
/** Verify that addressService addAddress was called once using Mockito **/
verify(addressService , times(1)).addAddress(addResult); 

L Jones
  • 60
  • 6
  • have you checked on which field you have the NPE? – Stultuske Mar 05 '20 at 13:24
  • In case you are using spring, you know that spring has its own way of doing unit testing, build around its DI mechanism? See https://stackoverflow.com/questions/21878714/how-to-write-junit-test-with-spring-autowire for example. – GhostCat Mar 05 '20 at 13:25
  • @Stultuske yes, it's the addResult. I added a comment next to it, indicating it has a NullPointerException – L Jones Mar 05 '20 at 15:20
  • @GhostCatsalutesMonicaC I prefer to use Mockito, as I need to test the service layer to not update database tables when testing. – L Jones Mar 05 '20 at 15:31
  • If you mock the `addressDataManager`, mocking the `addressRepo` (which seems to be a dependency of the `addressDataManager`) should not be necessary. Mocking the `addressService` does not help you, as mocking the class under test is not something you should do. – second Mar 05 '20 at 22:49
  • If you get a `NPE` it implies that your mock for `addressDataManager` is not properly injected (or can not be mocked). How does you constructor for your `AddressManager` look like? Maybe you can provide an example that includes these classes. – second Mar 05 '20 at 22:50

0 Answers0