尝试使用aem-mocks框架编写一些正确的AEM集成测试。目标是通过调用其路径来尝试测试servlet,
E.g。 AEM servlet
@SlingServlet(
paths = {"/bin/utils/emailSignUp"},
methods = {"POST"},
selectors = {"form"}
)
public class EmailSignUpFormServlet extends SlingAllMethodsServlet {
@Reference
SubmissionAgent submissionAgent;
@Reference
XSSFilter xssFilter;
public EmailSignUpFormServlet(){
}
public EmailSignUpFormServlet(SubmissionAgent submissionAgent, XSSFilter xssFilter) {
this.submissionAgent = submissionAgent;
this.xssFilter = xssFilter;
}
@Override
public void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
String email = request.getParameter("email");
submissionAgent.saveForm(xssFilter.filter(email));
}
}
以下是尝试进行集成测试的相应测试。请注意我是如何称呼servlet的“doPost'方法,而不是通过某些API进行POST。
public class EmailSignUpFormServletTest {
@Rule
public final AemContext context = new AemContext();
@Mock
SubmissionAgent submissionAgent;
@Mock
XSSFilter xssFilter;
private EmailSignUpFormServlet emailSignUpFormServlet;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
Map<String,String> report = new HashMap<>();
report.put("statusCode","302");
when(submissionAgent.saveForm(any(String.class)).thenReturn(report);
}
@Test
public void emailSignUpFormDoesNotRequireRecaptchaChallenge() throws IOException {
// Setup test email value
context.request().setQueryString("email=test.only@mail.com");
//===================================================================
/*
* WHAT I END UP DOING:
*/
// instantiate a new class of the servlet
emailSignUpFormServlet = new EmailSignUpFormServlet(submissionAgent, xssFilter);
// call the post method (Simulate the POST call)
emailSignUpFormServlet.doPost(context.request(),context.response());
/*
* WHAT I WOULD LIKE TO DO:
*/
// send request using some API that allows me to do post to the framework
// Example:
// context.request().POST("/bin/utils/emailSignUp") <--- doesn't exist!
//===================================================================
// assert response is internally redirected, hence expected status is a 302
assertEquals(302,context.response().getStatus());
}
}
我已经做了很多关于如何做到这一点的研究(here)和(here),这些链接显示了很多关于如何为上下文设置各种参数的信息.request()对象。但是,他们只是没有说明如何最终执行“帖子”。调用
答案 0 :(得分:1)
您要做的是将UT与IT混合使用,这至少对于aem-mocks框架来说并不容易。让我解释一下原因。
假设您可以拨打所需的代码
/*
* WHAT I WOULD LIKE TO DO:
*/
// send request using some API that allows me to do post to the framework
// Example:
// context.request().POST("/bin/utils/emailSignUp") <--- doesn't exist!
//===================================================================
您的测试将最终执行 SlingAllMethodsServlet 类及其父类中的所有逻辑。我假设这不是你想要测试的,因为这些类不是你的逻辑的一部分,他们已经有其他UT / IT(在各自的Apache项目下)以满足测试要求。
另外,查看代码时,核心逻辑的大部分内容都在以下代码中
String email = request.getParameter("email");
submissionAgent.saveForm(xssFilter.filter(email));
您的UT标准已通过以下代码行符合:
emailSignUpFormServlet.doPost(context.request(),context.response());
因为它涵盖了大部分逻辑。
现在,如果您正在寻找适当的IT来发布参数并将它们一直解析为doPost方法,那么aem-mocks就不是它的框架,因为它不能以简单的方式提供它。
理论上,您可以模拟资源解析器,资源提供程序和吊索servlet执行程序中的所有层,以将参数一直传递给核心逻辑。这可以工作,但它不会有益于你的事业,因为:
如果你真的想做纯IT,那么在一个实例中托管servlet并通过HttpClient访问它会更容易。这将确保所有图层都被击中。很多测试都是通过这种方式完成的,但是对于您想要测试的功能感觉有点沉重,并且有更好的方法。
另外context.request().POST
不存在的原因是因为context.request()
for是为了测试而被模拟的状态。您希望实际绑定和模拟Http.Post操作,这些操作需要某种方法来解析您的servlet,并且框架不支持。
希望这有帮助。