我需要编写一堆集成测试(Arquillian Framework),现在我在一些领域挣扎。这是控制器中方法的一个示例,该示例启动了jasper报告的创建,该报告随后将其流传输给客户端:
public void executeFibuAuswertung(){
Report report = reportService.find(99913L);
reportParameterForm.setReport(report);
List<ReportParameter> reportParameters = Collections.emptyList();
createExcelReport(reportParameters);
reportExecutionController.streamReportResult();
}
public void streamReportResult(){
EnumReportFormat format = reportParameterForm.getSelectedFormat();
ServletUtils.streamToClient(reportParameterForm.getReportResult()
, reportParameterForm.getReport().getTitle() + format.getFileExtention()
, format.getContentType()
, false);
facesContext.responseComplete();
}
如何使用Arquillian框架为此编写测试?
目前,我的测试看起来像这样:
@Before
public void before() {
FacesContext context = ContextMocker.mockFacesContext();
ContextMocker.mockPostback(context, false);
ContextMocker.mockFacesMessages(context);
ContextMocker.mockFindComponent(UIComponent.getCurrentComponent(context), context);
}
@Test(expected = NullPointerException.class)
@WindowScopeRequired
public void testExecuteAuswertung1() throws Exception {
fibuController.executeAuswertung();
byte[] content = reportParameterForm.getReportResult();
Assert.assertNotNull(content);
}
显然,这没什么意义。抛出NullPoInterException的以下代码行:
HttpServletResponse resp = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
这不是一个完整的答案,它是自以为是的
您的方法没有输入或输出(仅副作用),并且包含程序序列。如果可能的测试输入和预期值测试序列的每个步骤。 如果某些电话是由于某些原因直接测试使用真实组件的原因是不可行的,请嘲笑它们。如果您可以调用任何组件的某些方法,但其他部分不是可行的SPIE。
并尝试尽可能远离状态实现的设计和副作用。
这是我最终实现的解决方案:
@Mock
private HttpServletResponse httpServletResponse;
@Mock
private HttpServletRequest httpServletRequest;
@Mock
ExternalContext externalContext;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
FacesContext context = ContextMocker.mockFacesContext();
when(context.getExternalContext()).thenReturn(externalContext);
ContextMocker.mockPostback(context, false);
ContextMocker.mockFacesMessages(context);
ContextMocker.mockNavigationhandlers(context);
ContextMocker.mockFindComponent(UIComponent.getCurrentComponent(context), context);
}