Java:模拟对象未插入方法

时间:2018-12-17 08:30:23

标签: java unit-testing mocking mockito powermock

我要测试的代码行是:

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());
}

问题是测试用例不是选择模拟的Entity对象,而是选择在方法内部创建的entityList.get(0)

如何强制将模拟对象插入方法中,以便测试catch分支?

2 个答案:

答案 0 :(得分:0)

您需要嘲笑:

  • CoralHerdUtils.getRequestData返回模拟的ActionRequest
  • request.getHerdDocument返回模拟的Document
  • document.getEntitiesByType返回包含模拟的entity
  • 的列表

答案 1 :(得分:0)

真正的答案是:您必须了解什么是模拟以及模拟如何工作。

仅在某个地方创建模拟对象并不能神奇地将该对象“放入”被测代码中。

因此有一个独特的非答案:学习,然后将其应用于您的当前代码库(如用户talex所概述)。例如,开始阅读here

顺便说一句:到目前为止,您的生产代码中没有任何东西可以证明使用PowerMock(ito)是合理的。因此,如果可能,请与普通的Mockito呆在一起。