0

I have a class Room, where I inject Optional Person object, this is coming null while running testSuccess. My understanding is it should come non null, since I am setting this to new Person() at the start of the test. Why is it coming null?

public class Room{

    @Inject
    private Optional<Person> person1 
    //this is coming null when running test

}

My unit test

public class RoomTest {

    @Inject Mocks
    private Room testRoom

    .....
    //Other mocks

    private Optional<Person> testPerson
    //Not able to mock this since its optional, hence directly setting value in unit test.

    @Before
    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testSuccess() {
         testPerson = Optional.of(new Person());
         ....
         
    }

}

Aditya Mahajan
  • 303
  • 1
  • 3
  • 14
  • Does this answer your question? https://stackoverflow.com/questions/74027324/why-is-my-class-not-using-my-mock-in-unit-test – knittl Oct 11 '22 at 11:58

1 Answers1

0

As the name implies, @InjectMocks only injects @Mocks. The testPerson is not a mock. Why not just add an @Inject-ing constructor to the Room class that would accept a person? This way you could just instantiate a testRoom in your test method and your dependency injection will still work.

public class Room{
    private Optional<Person> person;

    @Inject
    public Room(Optional<Person> person) {
       this.person = person;
    }
}

public class RoomTest {
    @Test
    public void testSuccess() {
         Optional<Person> testPerson = Optional.of(new Person());
         Room room = new Room(testPerson);
         ...
    }

}

That said, if you absolutely want to use the annotations and adding the constructor is not an option for you then you can use PowerMock runner to mock the Optional. Conceptually, it can look like the code below. But usually, if you have to use PowerMock there might be something wrong with the code :)

public class Room{
    @Inject
    private Optional<Person> person;
}

// This is for JUnit4. Using Powermock with JUnit5 will be more involved
@RunWith(PowerMockitoRunner.class)
@PrepareForTest(Optional.class) // to mock the final class
public class RoomTest {
    @InjectMocks
    private Room testRoom;

    @Mock
    private Optional<Person> testPerson;

    @Before
    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testSuccess() {
        ...
    }
}
Dmitry Khamitov
  • 3,061
  • 13
  • 21