I’m using Mockito to test the following method:
protected void produceProducedFieldValue(Target target) throws ValueProducerCreationException { String mappedValue = (String) valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get(); target.setProducedField(mappedValue); }
Here is my test:
@Test public void TestProducingProducedFieldValue() throws ValueProducerCreationException { Target mockedTarget = Mockito.mock(Target.class); ValueProducerFactory valueProducerFactory = Mockito.mock(ValueProducerFactory.class); List<Object> creationParameters = new ArrayList<>(); String mappedValue= "SomeString"; Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue); SourceToTargetMapper sttm = new SourceToTargetMapper(targetModelObjectFactory,mappingOperatorFactory,mapperFactory,valueProducerFactory); sttm.produceProducedFieldValue(mockedTarget); Mockito.verify(mockedTarget, Mockito.times(1)).setProducedField(Mockito.any()); }
But I keep getting NullPointerExeption
for this line:
Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue);
ValueProducerFactory
is an Interface
and the createValueProducer
method signature is as follows:
public interface ValueProducerFactory { <T> Supplier<T> createValueProducer(String producerName, List<Object> creationParameters) throws ValueProducerCreationException; }
I have a class named CachingValueProducerFactory that implements the interface
@Override public <T> Supplier<T> createValueProducer(String producerName, List<Object> creationParameters) throws ValueProducerCreationException { Map<List<Object>, Supplier<?>> parametersToOperatorsMap = producersCache.computeIfAbsent(producerName, s -> new HashMap<>()); List<Object> key = Optional.ofNullable(creationParameters).orElse(Collections.emptyList()); if (!parametersToOperatorsMap.containsKey(key)) { parametersToOperatorsMap.put(key, nestedProducersFactory.createValueProducer(producerName, creationParameters)); } return (Supplier<T>) parametersToOperatorsMap.get(key); }
It seems like using Collections.emptyList()
in the test is the problem, but I don’t see any other solution for this.
Advertisement
Answer
You are trying to mock two methods at once. In this line:
Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue);
you are calling get()
on the result of the createValueProducer()
call, which is null
because you haven’t mocked it yet.
There are two solutions:
Use deep stubbing:
ValueProducerFactory valueProducerFactory = Mockito.mock(ValueProducerFactory.class, Mockito.RETURNS_DEEP_STUBS); Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue);
Mock the Supplier first (pay attention to the removed get()
):
Supplier<Object> supplier = () -> mappedValue; ValueProducerFactory valueProducerFactory = Mockito.mock(ValueProducerFactory.class); Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList())).thenReturn(supplier);