英文:
Null pointer exception when using Mockito to mock interface
问题
我正在使用Mockito测试以下方法:
```java
protected void produceProducedFieldValue(Target target) throws ValueProducerCreationException {
String mappedValue = (String) valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get();
target.setProducedField(mappedValue);
}
这是我的测试:
@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());
}
但是我一直在这一行中收到NullPointerException
:
Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue);
ValueProducerFactory
是一个接口
而createValueProducer
方法的签名如下:
public interface ValueProducerFactory {
<T> Supplier<T> createValueProducer(String producerName, List<Object> creationParameters) throws ValueProducerCreationException;
}
我有一个名为CachingValueProducerFactory的类,它实现了这个接口
@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);
}
似乎在测试中使用Collections.emptyList()
是问题所在,但我没有看到其他解决方案。
<details>
<summary>英文:</summary>
I'm using Mockito to test the following method:
```java
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.
答案1
得分: 1
你正在尝试同时模拟两个方法。在这一行中:
Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue);
你正在调用createValueProducer()
调用的结果上的get()
方法,因为你还没有模拟它,所以它是null
。
有两种解决方案:
使用深度存根:
ValueProducerFactory valueProducerFactory = Mockito.mock(ValueProducerFactory.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList()).get()).thenReturn(mappedValue);
首先模拟Supplier(注意已删除的get()
):
Supplier<Object> supplier = () -> mappedValue;
ValueProducerFactory valueProducerFactory = Mockito.mock(ValueProducerFactory.class);
Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList())).thenReturn(supplier);
英文:
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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论