Java: 未在方法中注入模拟对象
Java: Mocked object not being injected in method
我要测试的代码行是:
private static final EntityType WORK_FLOW_ENTITY_TYPE = //Assigned
public WorkflowRequest getWFRequestFromHerdInput(HerdInput herdInput) throws
NonRetriableException {
ActionRequest request = CoralHerdUtils.getRequestData(herdInput);
Document document = request.getHerdDocument();
List<Entity> entityList = document.getEntitiesByType(WORK_FLOW_ENTITY_TYPE);
Entity entity = entityList.get(0);
WorkflowRequest workflowRequest = null;
try {
workflowRequest = (WorkflowRequest) entity.asCommonsObject();
} catch (DocumentException e) {
throw new NonRetriableException("Object cannot be converted to WorkflowRequest");
}
return workflowRequest;
}
我想测试 try-catch 的 catch 部分。我同时使用 PowerMockito 和 Mockito。为了测试,我写了以下内容:
@Test(expected = NonRetriableException.class)
public void test_GetWFRequestFromHerdInput_fail() throws NonRetriableException, DocumentException {
PowerMockito.mockStatic(CoralHerdUtils.class);
PowerMockito.when(CoralHerdUtils.getRequestData(herdInput)).thenReturn(actionRequest);
EntityType WORKFLOW_ENTITYTYPE = new EntityType(new Aspect("DigitalInfluence"),
"Application", "1.0");
DocumentFactory docFactory = new DocumentFactory();
docFactory.registerCommonsClass(WorkflowRequest.class, WORKFLOW_ENTITYTYPE);
document = docFactory.createDocument();
document.addEntity(workflowRequest);
Mockito.when(actionRequest.getHerdDocument()).thenReturn(document);
List<Entity> entities = Mockito.mock(List.class);
Entity entity = Mockito.mock(Entity.class);
entities.add(entity);
Document documentMock = Mockito.mock(Document.class);
Mockito.when(documentMock.getEntitiesByType(WORKFLOW_ENTITYTYPE)).thenReturn(entities);
Mockito.when(entities.get(0)).thenReturn(entity);
Mockito.when(entity.asCommonsObject()).thenThrow(DocumentException.class);
WorkflowRequest workflowRequestReturned = herdDocumentHelper.getWFRequestFromHerdInput(herdInput);
Assert.assertEquals(EXPECTED_DAG_ID, workflowRequestReturned.getDagId());
}
问题是测试用例没有选择模拟的实体对象,而是选择在方法内部创建的 entityList.get(0)
。
如何在方法中强制注入模拟对象,以便测试 catch 分支?
你需要模拟:
CoralHerdUtils.getRequestData
到 return 嘲笑 ActionRequest
request.getHerdDocument
到 return 嘲笑 Document
document.getEntitiesByType
到 return 列表包含你的模拟 entity
真正的答案是:您必须了解模拟是什么以及它是如何工作的。
只是在某处创建一个模拟对象并不会神奇地"get"将该对象添加到您的测试代码中。
因此,一个明显的非答案:学习 模拟框架的工作原理,然后将其应用于您当前的代码库(如用户 talex 的答案中所述)。例如开始阅读 here。
顺便说一句:到目前为止,您的生产代码中没有任何内容证明可以使用 PowerMock(ito)。所以,如果可能的话,请继续使用普通的 Mockito。
我要测试的代码行是:
private static final EntityType WORK_FLOW_ENTITY_TYPE = //Assigned
public WorkflowRequest getWFRequestFromHerdInput(HerdInput herdInput) throws
NonRetriableException {
ActionRequest request = CoralHerdUtils.getRequestData(herdInput);
Document document = request.getHerdDocument();
List<Entity> entityList = document.getEntitiesByType(WORK_FLOW_ENTITY_TYPE);
Entity entity = entityList.get(0);
WorkflowRequest workflowRequest = null;
try {
workflowRequest = (WorkflowRequest) entity.asCommonsObject();
} catch (DocumentException e) {
throw new NonRetriableException("Object cannot be converted to WorkflowRequest");
}
return workflowRequest;
}
我想测试 try-catch 的 catch 部分。我同时使用 PowerMockito 和 Mockito。为了测试,我写了以下内容:
@Test(expected = NonRetriableException.class)
public void test_GetWFRequestFromHerdInput_fail() throws NonRetriableException, DocumentException {
PowerMockito.mockStatic(CoralHerdUtils.class);
PowerMockito.when(CoralHerdUtils.getRequestData(herdInput)).thenReturn(actionRequest);
EntityType WORKFLOW_ENTITYTYPE = new EntityType(new Aspect("DigitalInfluence"),
"Application", "1.0");
DocumentFactory docFactory = new DocumentFactory();
docFactory.registerCommonsClass(WorkflowRequest.class, WORKFLOW_ENTITYTYPE);
document = docFactory.createDocument();
document.addEntity(workflowRequest);
Mockito.when(actionRequest.getHerdDocument()).thenReturn(document);
List<Entity> entities = Mockito.mock(List.class);
Entity entity = Mockito.mock(Entity.class);
entities.add(entity);
Document documentMock = Mockito.mock(Document.class);
Mockito.when(documentMock.getEntitiesByType(WORKFLOW_ENTITYTYPE)).thenReturn(entities);
Mockito.when(entities.get(0)).thenReturn(entity);
Mockito.when(entity.asCommonsObject()).thenThrow(DocumentException.class);
WorkflowRequest workflowRequestReturned = herdDocumentHelper.getWFRequestFromHerdInput(herdInput);
Assert.assertEquals(EXPECTED_DAG_ID, workflowRequestReturned.getDagId());
}
问题是测试用例没有选择模拟的实体对象,而是选择在方法内部创建的 entityList.get(0)
。
如何在方法中强制注入模拟对象,以便测试 catch 分支?
你需要模拟:
CoralHerdUtils.getRequestData
到 return 嘲笑ActionRequest
request.getHerdDocument
到 return 嘲笑Document
document.getEntitiesByType
到 return 列表包含你的模拟entity
真正的答案是:您必须了解模拟是什么以及它是如何工作的。
只是在某处创建一个模拟对象并不会神奇地"get"将该对象添加到您的测试代码中。
因此,一个明显的非答案:学习 模拟框架的工作原理,然后将其应用于您当前的代码库(如用户 talex 的答案中所述)。例如开始阅读 here。
顺便说一句:到目前为止,您的生产代码中没有任何内容证明可以使用 PowerMock(ito)。所以,如果可能的话,请继续使用普通的 Mockito。