How to inject fields using Mockito without specifying them in constructor?

I have a class (PriceSetter) that I’m testing with Mockito, and the class has an internal dependency (a database). I want to mock this internal dependency and then inject it into the class, but the dependency is not specified in my constructor. Thus, Mockito automatically tries to do constructor injection and the dependency never gets injected.

I tried using @Mock on my database object and @InjectMocks on my PriceSetter class, but Mockito automatically calls the constructor, and it fails to inject my database mock as the database is not passed into the constructor.

class PriceSetter {
    private Table priceTable;

    public PriceSetter(Dependency d1, Dependency d2) {
        this.d1 = d1;
        this.d2 = d2;
    }
}

@RunWith(MockitoJUnitRunner.class)
class PriceSetterTest{
    @InjectMocks
    private PriceSetter setter;

    @Mock Table priceTable;
    @Mock Dependency d1;
    @Mock Dependency d2;

    @Test
    public void someTestMethod() {
        when(priceTable.getItem(any())).thenReturn(Specified item);
        setter.priceTable.getItem("item"); -> Doesn't return item specified by mocked behavior
    }
}

I expect priceTable to be injected, but it isn’t injected. Only d1 and d2 are injected through constructor injection.

Answer

@InjectMocks will only do one of constructor injection or property injection, not both.

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order…

You can always do

@Before
public void setUp() {
   setter.setPriceTable(priceTable);
}

Or however your table should get wired. However, the cleanest design is typically to unify your dependency injection method to inject everything into the constructor. Since @InjectMocks will choose the biggest constructor and work on private or package-private constructors, one option would be to add a constructor overload:

class PriceSetter {
    private Table priceTable;

    public PriceSetter(Dependency d1, Dependency d2) {
        this(d1, d2, new DefaultPriceTable());
    }

    PriceSetter(Dependency d1, Dependency d2, Table priceTable) {
        this.d1 = d1;
        this.d2 = d2;
        this.priceTable = priceTable;
    }

}