Trying to run a JUnit test with Mockito but you find that your mocks aren't injecting? Hey, I've been there.

And in this guide, I'll show you how to get out of there.

At least, I'll show you how I did it. And it might very well be the answer for you as well.

NullPointerException

If you're here because you're getting the dreaded NullPointerException when using Mockito with mocks, then you're encountering the same problem I experienced.

Let me show you some code.

@RunWith(MockitoJUnitRunner.class)
public class RegistrantServiceTest {

    @Mock
    private UserService userService;

    @Mock
    private UserRepository userRepository;

    @Mock
    private UserUtil userUtil;

    @Mock
    private RecaptchaUtil recaptchaUtil;

    @Mock
    private TotpUtil totpUtil;

    @Mock
    private RegistrantAuthenticationRepository registrantAuthenticationRepository;

    @Mock
    private EmailService emailService;

    @Mock
    private SmsService smsService;
    
    @InjectMocks
    private RegistrantService registrantService;
    
    @Test
    public void testSaveUserWithSuccess() {
        Registrant registrant = UserHarness.getValidRegistrant();
        User user = UserHarness.getValidUser();
        
        Mockito.when(userUtil.convertRegistrantToUser(registrant)).thenReturn(user);
        Mockito.when(userRepository.save(Mockito.any(User.class))).thenReturn(user);
        
        User savedUser = registrantService.saveUser(registrant);
        
        Assertions.assertNotNull(savedUser);
        Assertions.assertEquals(UserHarness.VALID_EMAIL_ADDRESS, savedUser.getEmail());
        Assertions.assertEquals(UserHarness.VALID_FIRST_NAME, savedUser.getFirstName());
        Assertions.assertEquals(UserHarness.VALID_LAST_NAME, savedUser.getLastName());
    }

...

}

When I run that unit test, I get a NullPointerException. But why?

Probably because I, like you, relied a little too heavily on online advice columnists.

You may have used your favorite search engine to look for some pointers on how to test the service layer and found some JUnit/Mockito code samples that look like what you see above.

So you followed the pattern.

You annotated the class with @RunWith(MockitoJUnitRunner.class), set up your mocks, and injected your mocks with @InjectMocks.

And according to what people not named Brian Carey have told you, that should work.

But it didn't.

You got a NullPointerException when you ran that.

Specifically, the null is in the first Mockito.when() line.

What happened?

Here's what happened: you're living in the past.

The Dark Ages

You're coding with JUnit/Mockito technology that was invented back in the Dark Ages. You need to join the Renaissance.

Youre likely using JUnit 5. And JUnit 5 doesn't use @RunWith. JUnit 4 did.

Take another look at how that class above is annotated:

@RunWith(MockitoJUnitRunner.class)
public class RegistrantServiceTest {

...

}

It's annotated with @RunWith. That's (probably) why you're having problems.

With JUnit 5, try @ExtendWith. Like this:

@ExtendWith(MockitoExtension.class)
public class RegistrantServiceTest {

...

}

Note that it's using a different class in the parentheses as well. It's using MockitoExtension.class instead of MockitoJUnitRunner.class.

Now if I run my test again, it works. My mocks get injected and my test passes.

And that might just do the trick for you as well. At least I hope so.

Wrapping It Up

I think it's great to run tests with JUnit and Mockito. But you gotta know how to do it correctly.

Unfortunately, there's still quite a bit of "old school" info out there. That's why I wrote this guide.

Feel free to take what you've learned here and use it in your own testing efforts.

Have fun!

Photo by Andrea Piacquadio from Pexels