Mockito mock没有按预期工作Mockito-3.12.4



我正在尝试为MessageFacade.java类的以下方法编写JUnit测试

public void delete(FooId scopeId, DataId id)
throws FooIllegalArgumentException,
ConfigurationException,
ClientException {
ArgumentValidator.notNull(scopeId, SCOPE_ID);
ArgumentValidator.notNull(id, "id");
System.out.println("Query Param SCOPE_ID="+scopeId.getId().toString());
System.out.println("Query Param ID="+id.toString());
if (!isDatastoreServiceEnabled(scopeId)) {
LOG.debug("Storage not enabled for account {}, return", scopeId);
return;
}
//ORIGINAL CODE
DatastoreMessage messageToBeDeleted = find(scopeId, id, DataFetchStyle.FIELDS);
if (messageToBeDeleted != null) {
Metadata schemaMetadata = null;
try {
schemaMetadata = mediator.getMetadata(scopeId, messageToBeDeleted.getTimestamp().getTime());
} catch (FooException e) {
LOG.warn("Retrieving metadata error", e);
}
String indexName = schemaMetadata.getDataIndexName();
TypeDescriptor typeDescriptor = new TypeDescriptor(indexName, MessageSchema.MESSAGE_TYPE_NAME);
ElasticsearchClient elasticsearchClient = getElasticsearchClient();
elasticsearchClient.delete(typeDescriptor, id.toString());
} else {
LOG.warn("Cannot find the message to be deleted. scopeId: '{}' - id: '{}'", scopeId, id);
}
}

我已经为上述方法编写了以下JUnit测试

@Test
public void testBulkDelete() throws ClientException, ConfigurationException, FooIllegalArgumentException {
MessageFacade messageFacade = new MessageFacade(Mockito.mock(ConfigurationProvider.class),Mockito.mock(MessageStoreMediator.class));
MessageFacade spyMessageFacade = Mockito.spy(messageFacade);
DatastoreMessage datastoreMessage = new DatastoreMessageImpl();
datastoreMessage.setTimestamp(new Date());
Mockito.doReturn(datastoreMessage).when(spyMessageFacade).find(Mockito.any(),Mockito.any(),Mockito.any());
Metadata schemaMetadata = Mockito.mock(Metadata.class);
Mockito.doReturn("indexName").when(schemaMetadata).getDataIndexName();
ElasticsearchClient elasticsearchClient = Mockito.mock(ElasticsearchClient.class);
Mockito.doNothing().when(elasticsearchClient).delete(Mockito.any(TypeDescriptor.class), Mockito.any(String.class));
Mockito.doReturn(true).when(spyMessageFacade).isDatastoreServiceEnabled(Mockito.any());
FooId scopeId = new ScopeId("10");
DataId id = new DataIdImpl("c17db8ea-93ee-48b5-9b5d-8d278180d2d9");
spyMessageFacade.delete(scopeId, id);
}

我使用的是JUnit 4.12Mockito 3.12.4版本

问题是以下线路(242号线路(没有被模拟schemaMetadata.getDataIndexName();

并抛出NullPointerException,如下面的跟踪所示

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Query Param SCOPE_ID=-41
Query Param ID=c17db8ea-93ee-48b5-9b5d-8d278180d2d9
java.lang.NullPointerException
at org.mars.foo.service.datastore.internal.MessageFacade.delete(MessageFacade.java:242)
at org.mars.foo.service.datastore.internal.MessageFacadeTest.testBulkDelete(MessageFacadeTest.java:74)
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.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.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)

此外,我需要一些关于如何模拟线路的建议elasticsearchClient.delete(typeDescriptor, id.toString());

您正面临这个问题,因为Metadata schemaMetadata是一个局部变量,它正在被替换。

您可以模拟mediator.getMetadata调用,以使用创建的元数据对象返回模拟。我有很多这样的案例,通常我会使用它。

模拟这个:

mediator.getMetadata(scopeId, messageToBeDeleted.getTimestamp().getTime());

这边:

when(mediator.getMetadata(any(), any()).thenReturn(new Metadata(){{
setDataIndexName("IndexName"):
}};);

显然,在使用when之前,您需要模拟mediator

它对我有用,我希望它也能帮助你。

最新更新