简体   繁体   中英

Mockito - how to inject final field marked as @Mock by constructor when using @Spy and @InjectMocks

I have a special case, where I have to mock some fields and use both @Mock and @Spy for my class, which is under test, because at some tests I need to change behaviour of it's own methods. I use @InjectMocks for constructor. It looks like this:

Test class:

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

    @Mock
    private SomeObject usedAsNonFinal;

    @Mock
    private SomeObject usedAsFinal;

    @Spy
    @InjectMocks
    private ServiceTest service = new ServiceTest(usedAsNonFinal, usedAsFinal);

    @Before
    public void setup() {
        when(usedAsNonFinal.someMethod(Matchers.any()))
                .thenReturn(someObject);

        when(usedAsFinal.someMethod(Matchers.any()))
                .thenReturn(someObject);

        doReturn(someObject).when(service).someMethod(Matchers.any());
    }
}

Service, which is under test:

@Service
public class Service {

    private SomeObject usedAsNonFinal //injects correctly

    private final SomeObject usedAsFinal; //null - not injected

    @Autowired
    public Service (SomeObject usedAsNonFinal, SomeObject usedAsFinal){
    this.usedAsNonFinal = usedAsNonFinal;
    this.usedAsFinal = usedAsFinal;
    }

    //some methods to mock depending on test
}

The problem is - as commented in code - that final field is not getting injected and it's null. When I remove final keyword it gets injected correctly and all tests are working as expected. I tried some tricks from other topics - also using reflection, but nothing seems to be workking in this particular case.

Did you try don't instantiate ServiceTest in test?

@InjectMocks should do it for you. Try just

@Spy
@InjectMocks
private ServiceTest service;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM