【问题标题】:Null pointer exception when using Mockito to mock interface使用 Mockito 模拟接口时出现空指针异常
【发布时间】:2020-10-16 20:44:42
【问题描述】:

我正在使用 Mockito 测试以下方法:

  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());
    }

但我不断收到 NullPointerExeption 这条线路:

    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() 是问题所在,但我没有看到任何其他解决方案。

【问题讨论】:

    标签: java unit-testing nullpointerexception mockito


    【解决方案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);
    

    先Mock the Supplier(注意被删除的get()):

    Supplier<Object> supplier = () -> mappedValue;
    ValueProducerFactory valueProducerFactory = Mockito.mock(ValueProducerFactory.class);
    Mockito.when(valueProducerFactory.createValueProducer("IdProducer", Collections.emptyList())).thenReturn(supplier);
    

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 2019-12-26
      相关资源
      最近更新 更多