【问题标题】:Best way for testing service-layer by MockitoMockito 测试服务层的最佳方法
【发布时间】:2020-03-17 07:28:30
【问题描述】:

我是 Mockito 的新手。我有一个服务层,它使用一些存储库来查询数据库。我需要测试那个层。该服务有几个配置文件(dev/prod/stage)所以我需要做这个测试独立于配置文件。 我决定使用 Mockito。当我尝试模拟我的存储库时遇到了问题。

服务

@Autowired
RestLogRepositoryCustomImpl restLogRepositoryCustom;

public List<RestLogDto> readLogs(Integer page, Integer size, ZonedDateTime userFromDate, ZonedDateTime userToDate) {
ZonedDateTime toDate = Optional
    .ofNullable(userToDate)
    .orElseGet(() -> Optional
        .ofNullable(userFromDate)
        .orElseGet(ZonedDateTime::now)
        .plusDays(1)
        .truncatedTo(ChronoUnit.DAYS)
        .minusNanos(1));

ZonedDateTime fromDate = Optional
    .ofNullable(userFromDate)
    .filter(date -> ChronoUnit.HOURS.between(date, toDate) < 24)
    .orElseGet(() -> Optional
        .ofNullable(userToDate)
        .orElseGet(ZonedDateTime::now)
        .truncatedTo(ChronoUnit.DAYS)
        .minusDays(1));

return restLogRepositoryCustom.getAllJoinedRecords(
    PageRequestUtils.of(
        page, size, PageRequestUtils.pageOf(), PageRequestUtils.sizeOf(5, 200)),
    Date.from(fromDate.toInstant()),
    Date.from(toDate.toInstant()));
}

测试服务

@RunWith(MockitoJUnitRunner.Silent.class)

public class DBLogReaderTest {

private static final Long LOG_ID = 1L;
private static final String JAVA_ID = "1ID";
private static final String MESSAGE = "message";

private static ModelMapper mapper;

@InjectMocks
private DBLogReader logReader;

@Mock
private RestLogRepository restLogRepository;

@Mock
private RestLogRepositoryCustomImpl restLogRepositoryCustom;

@Before
public void setup() {
    mapper = new ModelMapper();
    logReader = new DBLogReader(mapper);
}

@Test
public void contextLoad() {
    assertThat(logReader).isNotNull();
}

@Test
public void readLogs() {
    RestLogDto log = new RestLogDto();
    log.setId(LOG_ID);

    List<RestLogDto> logList = new ArrayList<>();
    logList.add(log);

    when(restLogRepositoryCustom.getAllJoinedRecords(
        any(PageRequest.class), any(Date.class), any(Date.class))
    ).thenReturn(logList);

    assertEquals(logReader.readLogs(0, 10, ZonedDateTime.now().minusHours(23), ZonedDateTime.now()), logList);
}

我认为在我的服务中包含restLogRepositoryCustom.getAllJoinedRecords()logReader.readLogs() 将返回一个logList,但那不是这样,所以我在restLogRepositoryCustom.getAllJoinedRecords() 中得到了一个空指针异常服务层。

堆栈跟踪

java.lang.NullPointerException
at ru.logsmanager.service.DBLogReader.readById(DBLogReader.java:62)
at ru.logsmanager.service.DBLogReaderTest.readById(DBLogReaderTest.java:78)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

问题:如何在 logReaderService 中模拟方法?

【问题讨论】:

    标签: java spring-boot unit-testing spring-mvc mockito


    【解决方案1】:

    当你这样做时

     logReader = new DBLogReader(mapper);
    

    您正在创建一个新的 logReader 实例。但是你没有注入模拟。

    @InjectMocks 注释已经为您完成了这项工作。您不需要手动实例化。

    我需要查看完整的代码才能确定,但​​我认为如果你删除这行代码会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-28
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多