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。