I have the following code:
@Component public class Wrapper { @Resource private List<Strategy> strategies; public String getName(String id) { // the revelant part of this statement is that I would like to iterate over "strategies" return strategies.stream() .filter(strategy -> strategy.isApplicable(id)) .findFirst().get().getAmount(id); } }
@Component public class StrategyA implements Strategy{...} @Component public class StrategyB implements Strategy{...}
I would like to create a Test for it using Mockito. I wrote the test as follows:
@InjectMocks private Wrapper testedObject = new Wrapper (); // I was hoping that this list will contain both strategies: strategyA and strategyB @Mock private List<Strategy> strategies; @Mock StrategyA strategyA; @Mock StrategyB strategyB; @Test public void shouldReturnNameForGivenId() { // irrevelant code... //when testedObject.getName(ID); }
I am getting NullPointerException on line:
filter(strategy -> strategy.isApplicable(id))
, which states that the "strategies" list is initialized but is empty. Is there any way Mohito will behave in the same wasy as Spring? Adding automatically all instances implementing interface "Strategy" to the list?
Btw I do not have any setters in Wrapper class and I would like to leave it in that way if possible.
@InjectMocks creates an instance of the class and injects the mocks that are created with the @Mock annotations into this instance. @Mock is used to create mocks that are needed to support the testing of the class to be tested. @InjectMocks is used to create class instances that need to be tested in the test class.
Mockito @InjectMocks annotations allow us to inject mocked dependencies in the annotated class mocked object. This is useful when we have external dependencies in the class we want to mock. We can specify the mock objects to be injected using @Mock or @Spy annotations.
@InjectMocks is the Mockito Annotation. It allows you to mark a field on which an injection is to be performed. Injection allows you to, Enable shorthand mock and spy injections.
Main difference between @MockBean and @Mock annotation is that @MockBean creates mock and injects it into Application Context, while @Mock annotation only creates it, if you want to inject it, you can do it manually or with @InjectMocks annotation, however injection is being done to the class not whole Application ...
Annotate it with @Spy instead of @Mock. As Mockito cannot spy on an interface, use a concrete implementation, for example ArrayList. During test setup add the mocks to the List spy. This way you do not need to alter your test subject solely for test purposes.
@InjectMocks private Wrapper testedObject = new Wrapper(); @Spy private ArrayList<Strategy> mockedStrategies; @Mock private StrategyA strategyA; @Mock private StrategyB strategyB; @Before public void setup() throws Exception { mockedStrategies.add(strategyA); mockedStrategies.add(strategyB); }
Mockito can not know that you want to put somthing in the List strategies.
You should rethink this an do something like this
@InjectMocks private Wrapper testedObject = new Wrapper (); private List<Strategy> mockedStrategies; @Mock StrategyA strategyA; @Mock StrategyB strategyB; @Before public void setup() throws Exception { mockedStrategies = Arrays.asList(strategyA, strategyB); wrapper.setStrategies(mockedStrategies); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With