Bird
Raised Fist0
JUnittesting~15 mins

@InjectMocks annotation in JUnit - Build an Automation Script

Choose your learning style10 modes available
Automate unit test using @InjectMocks to inject mock dependencies
Preconditions (3)
Step 1: Create a mock instance of the repository interface using @Mock
Step 2: Create an instance of the service class using @InjectMocks to inject the mock repository
Step 3: Stub the repository method to return a fixed value
Step 4: Call the service method that uses the repository
Step 5: Verify the service method returns the expected value based on the stubbed repository
✅ Expected Result: The service method returns the expected value from the mocked repository without null pointer exceptions
Automation Requirements - JUnit 5 with Mockito
Assertions Needed:
Assert that the service method returns the stubbed value
Verify that the repository method was called exactly once
Best Practices:
Use @ExtendWith(MockitoExtension.class) to enable Mockito annotations
Use @Mock for dependencies
Use @InjectMocks for the class under test
Use Mockito's when-thenReturn for stubbing
Use verify to check interactions
Keep test methods small and focused
Automated Solution
JUnit
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    @Mock
    UserRepository userRepository;

    @InjectMocks
    UserService userService;

    @Test
    void testGetUserNameReturnsStubbedName() {
        // Arrange: stub repository method
        when(userRepository.findUserNameById(1)).thenReturn("Alice");

        // Act: call service method
        String result = userService.getUserName(1);

        // Assert: verify returned value
        assertEquals("Alice", result);

        // Verify repository method was called once
        verify(userRepository, times(1)).findUserNameById(1);
    }
}

// Supporting classes
interface UserRepository {
    String findUserNameById(int id);
}

class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public String getUserName(int id) {
        return userRepository.findUserNameById(id);
    }
}

This test class uses @ExtendWith(MockitoExtension.class) to enable Mockito annotations.

The @Mock annotation creates a mock instance of UserRepository.

The @InjectMocks annotation creates an instance of UserService and injects the mocked UserRepository into it.

In the test method, we stub the repository method findUserNameById to return "Alice" when called with 1.

We then call the service method getUserName and assert it returns "Alice".

Finally, we verify that the repository method was called exactly once.

This setup ensures the service is tested in isolation with controlled dependencies.

Common Mistakes - 4 Pitfalls
{'mistake': 'Not using @ExtendWith(MockitoExtension.class) causing @Mock and @InjectMocks not to work', 'why_bad': "Mockito annotations won't be processed, mocks won't be created, leading to NullPointerException", 'correct_approach': 'Always add @ExtendWith(MockitoExtension.class) on the test class to enable Mockito annotations'}
{'mistake': 'Manually instantiating the class under test instead of using @InjectMocks', 'why_bad': "Mocks won't be injected automatically, dependencies will be null or real instances", 'correct_approach': 'Use @InjectMocks to let Mockito create the class and inject mocks automatically'}
Forgetting to stub mock methods before calling service methods
Using field injection in the class under test instead of constructor injection
Bonus Challenge

Now add data-driven testing with 3 different user IDs and expected names

Show Hint

Practice

(1/5)
1. What is the primary purpose of the @InjectMocks annotation in JUnit testing?
easy
A. To spy on real objects without mocking
B. To create the class under test and inject mock dependencies automatically
C. To create mock objects without injecting them
D. To run tests in parallel threads

Solution

  1. Step 1: Understand the role of @InjectMocks

    @InjectMocks creates an instance of the class under test and injects mocks into it automatically.
  2. Step 2: Compare with other annotations

    @Mock creates mock objects, but does not inject them. @Spy wraps real objects. @InjectMocks handles injection.
  3. Final Answer:

    To create the class under test and inject mock dependencies automatically -> Option B
  4. Quick Check:

    @InjectMocks = auto-inject mocks [OK]
Hint: Remember: @InjectMocks builds and injects mocks automatically [OK]
Common Mistakes:
  • Confusing @InjectMocks with @Mock
  • Thinking @InjectMocks creates mocks instead of injecting
  • Assuming @InjectMocks runs tests or manages threads
2. Which of the following is the correct way to declare a field with @InjectMocks in a JUnit 5 test class?
easy
A. @InjectMocks private Service service;
B. @InjectMocks Service service = new Service();
C. @InjectMocks private Service service = new Service();
D. @InjectMocks Service service;

Solution

  1. Step 1: Check field declaration syntax

    Fields with @InjectMocks should be private and declared without manual instantiation.
  2. Step 2: Identify correct syntax

    @InjectMocks private Service service; declares a private field with @InjectMocks without manual instantiation, letting the framework create it.
  3. Final Answer:

    @InjectMocks private Service service; -> Option A
  4. Quick Check:

    Private field + no manual new = correct [OK]
Hint: Use private fields without 'new' for @InjectMocks [OK]
Common Mistakes:
  • Manually instantiating the field defeats @InjectMocks purpose
  • Using package-private or public fields without private
  • Missing semicolon or incorrect syntax
3. Given the following test code snippet, what will be the output of service.process() if dependency.doWork() is mocked to return "mocked"?
class Dependency {
    String doWork() { return "real"; }
}

class Service {
    Dependency dependency;
    String process() { return dependency.doWork(); }
}

@InjectMocks
Service service;

@Mock
Dependency dependency;

@BeforeEach
void setup() {
    MockitoAnnotations.openMocks(this);
    when(dependency.doWork()).thenReturn("mocked");
}

@Test
void testProcess() {
    System.out.println(service.process());
}
medium
A. Compilation error
B. "real"
C. NullPointerException
D. "mocked"

Solution

  1. Step 1: Understand @InjectMocks and @Mock interaction

    @InjectMocks creates Service and injects the mocked Dependency instance into it.
  2. Step 2: Analyze method call and mock behavior

    dependency.doWork() is mocked to return "mocked", so service.process() returns "mocked".
  3. Final Answer:

    "mocked" -> Option D
  4. Quick Check:

    Mocked method returns "mocked" [OK]
Hint: Mocks override real methods; expect mocked return values [OK]
Common Mistakes:
  • Expecting real method output instead of mocked
  • Forgetting to initialize mocks with openMocks
  • Assuming dependency is null causing NullPointerException
4. Consider the following test setup:
@InjectMocks
Service service;

@Mock
Dependency dependency;

@BeforeEach
void setup() {
    MockitoAnnotations.openMocks(this);
}

@Test
void test() {
    System.out.println(service.process());
}

When running the test, a NullPointerException occurs at service.process(). What is the most likely cause?
medium
A. The @InjectMocks annotation is applied to the wrong class
B. The @Mock annotation is missing
C. The dependency field in Service is not initialized or injected
D. MockitoAnnotations.openMocks(this) was not called

Solution

  1. Step 1: Identify cause of NullPointerException

    NullPointerException at service.process() means dependency inside Service is null.
  2. Step 2: Check injection of mocks

    @InjectMocks should inject mocks into Service fields, but if Service's dependency field is not properly declared or missing setter, injection fails.
  3. Final Answer:

    The dependency field in Service is not initialized or injected -> Option C
  4. Quick Check:

    NullPointerException = missing injection [OK]
Hint: NullPointerException often means mock not injected properly [OK]
Common Mistakes:
  • Assuming missing @Mock causes NPE (it causes different errors)
  • Thinking openMocks call is missing when it is present
  • Confusing @InjectMocks placement with injection failure
5. You have a class OrderService that depends on PaymentService and InventoryService. You want to write a JUnit test using @InjectMocks to inject mocks of both dependencies. Which setup correctly uses @InjectMocks and @Mock to achieve this?
hard
A. @InjectMocks OrderService orderService; @Mock PaymentService paymentService; @Mock InventoryService inventoryService;
B. @Mock OrderService orderService; @InjectMocks PaymentService paymentService; @InjectMocks InventoryService inventoryService;
C. @InjectMocks OrderService orderService = new OrderService(); @Mock PaymentService paymentService; @Mock InventoryService inventoryService;
D. @Mock OrderService orderService; @Mock PaymentService paymentService; @Mock InventoryService inventoryService;

Solution

  1. Step 1: Identify the class under test

    OrderService is the class under test, so it should be annotated with @InjectMocks.
  2. Step 2: Identify dependencies to mock

    PaymentService and InventoryService are dependencies, so they should be annotated with @Mock.
  3. Step 3: Check for manual instantiation

    OrderService should not be manually instantiated when using @InjectMocks to allow automatic injection.
  4. Final Answer:

    @InjectMocks OrderService orderService; @Mock PaymentService paymentService; @Mock InventoryService inventoryService; -> Option A
  5. Quick Check:

    Class under test @InjectMocks + dependencies @Mock [OK]
Hint: InjectMocks on class under test; Mocks on dependencies [OK]
Common Mistakes:
  • Annotating dependencies with @InjectMocks instead of @Mock
  • Manually instantiating class under test with @InjectMocks
  • Annotating class under test with @Mock instead of @InjectMocks
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard