在JUnit 5测试中模拟EhCache NullPointerException

时间:2019-03-13 11:34:29

标签: java junit mockito ehcache

我正在为要测试的服务编写单元测试。有几种方法尝试从EhCache检索值。 我尝试使用Mockito来模拟它们,并且只是让get(String key)的{​​{1}}方法返回null,因为我想忽略这些测试的缓存。

我的考试班:

Cache

我的实现:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import com.jysk.dbl.esldataservice.model.Preis;
import com.jysk.dbl.esldataservice.service.PreisService;
import com.jysk.dbl.esldataservice.service.external.PimDataService;
import com.jysk.dbl.esldataservice.service.external.SapCarService;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;

public class PreisServiceTest {

    @Mock
    private SapCarService sapCarService;
    @Mock
    private ArticleDataService articleDataService;
    @Mock
    private CacheManager cacheManager;
    @Mock
    private Cache cache;

    @InjectMocks
    @Resource
    private PreisService preisService;

    @BeforeEach
    public void setup() {

        MockitoAnnotations.initMocks(this);

        when(this.cacheManager.getCache(anyString())).thenReturn(this.cache);
        when(this.cache.get(anyString())).then(null);
    }

    protected static final String TEST_STORE_IDENTIFIER = "1234";
    private static final String ARTICLE_IDENTIFIER_1 = "12345001";
    private static final String ARTICLE_IDENTIFIER_2 = "54321001";

    private final Preis p1 = new Preis(ARTICLE_IDENTIFIER_1, 10.00, 15.00, "01", "01", "01");
    private final Preis p2 = new Preis(ARTICLE_IDENTIFIER_2, 20.00, 25.00, "02", "02", "02");

    @Test
    void testGetPreisReturnsOneCorrectPreis() {

        when(this.sapCarService.getPreise(Arrays.asList(ARTICLE_IDENTIFIER_1), TEST_STORE_IDENTIFIER, true)).thenReturn(Arrays.asList(this.p1));

        final List<Preis> actual = this.preisService.getPreis(ARTICLE_IDENTIFIER_1, TEST_STORE_IDENTIFIER);

        verify(this.sapCarService, times(1)).getPreise(anyList(), anyString(), anyBoolean());

        assertNotNull(actual);
        assertEquals(1, actual.size());
        assertEquals(this.p1, actual);
    }
}

stackTrace显示,NPE被抛出到private Preis searchPreisInCache(String key) { final Element preisOptional = this.cacheManager.getCache("preis").get(key); // NPE here if (preisOptional != null) { final Preis preis = (Preis) preisOptional.getObjectValue(); logger.info(String.format("Preis with key '%s' found in cache 'preis'.", key)); return preis; } return null; } 类中:

net.sf.ehcache.Cache

如果我只是想让public final Element get(Object key) throws IllegalStateException, CacheException { getObserver.begin(); // NPE thrown here checkStatus(); if (disabled) { getObserver.end(GetOutcome.MISS_NOT_FOUND); return null; } Element element = compoundStore.get(key); if (element == null) { getObserver.end(GetOutcome.MISS_NOT_FOUND); return null; } else if (isExpired(element)) { tryRemoveImmediately(key, true); getObserver.end(GetOutcome.MISS_EXPIRED); return null; } else if (!skipUpdateAccessStatistics(element)) { element.updateAccessStatistics(); } getObserver.end(GetOutcome.HIT); return element; } 在每次调用时返回Cache,是否有解决此问题的简便方法?

1 个答案:

答案 0 :(得分:1)

Mockito在没有进行某些配置的情况下无法模拟final的方法和类。正如Morfic指出的那样,Mockito v2.x是可以实现的,就像解释的herehere一样。

基本上,您必须在目录org.mockito.plugins.MockMaker下添加一个名为src/test/resources/mockito-extensions的文本文件,其内容为mock-maker-inline和tada,Mockito可以模拟最终方法和类。 / p>

但是,这使用了具有不同限制的不同引擎,所以请注意这一点。