我想对通过外部访问管理基础结构登录用户的方法进行单元测试。我不知道如何嘲笑Response response
对象。
这是我打算测试的代码:
public String login(final String username, final String password) {
String baseUrl = getOpenAMApiBaseUrl();
String path = "/openam/json/authenticate";
// Response NEEDS TO BE MOCKED SOMEHOW
Response response = jaxClient.target(baseUrl + path)
.request(MediaType.APPLICATION_JSON_TYPE)
.header(HttpHeaderField.OPENAM_USERNAME, username)
.header(HttpHeaderField.OPENAM_PASSWORD, password)
.post(Entity.json(null));
int status = response.getStatus();
String jsonResponse = response.readEntity(String.class);
if (status == Response.Status.OK.getStatusCode()) {
try (JsonReader jsonReader = Json.createReader(new StringReader(jsonResponse))) {
JsonObject jsonObject = jsonReader.readObject();
String token = jsonObject.getString("tokenId");
LOGGER.info("{} have successfully logged in", username);
return token;
} catch (NullPointerException e) {
LOGGER.info("login failed, invalid json response for {}/{}", username, password);
return null;
}
}
String message = "an error occurred during logging in, http status: {}, user: {}/{}";
if (status == Response.Status.UNAUTHORIZED.getStatusCode()) {
message = "invalid credentials, http status: {}, user: {}/{}";
}
LOGGER.info(message, status, username, password);
return null;
}
理想情况下,您必须从jaxClient.target
方法开始模拟所有调用,但在这种情况下,由于生成模拟需要很长的链,我建议以下两种选择之一:
1)(可推荐)- 将响应的创建提取到仅专门用于该特定操作的新类。
然后,您将该类声明为被测试类的依赖项,只需使用配置为返回某个响应对象的构建器方法注入它的模拟。
2)您可以在类中创建包级方法,如下所示:
Response buildResponse(){
String baseUrl = getOpenAMApiBaseUrl();
String path = "/openam/json/authenticate";
// Response NEEDS TO BE MOCKED SOMEHOW
Response response = jaxClient.target(baseUrl + path)
.request(MediaType.APPLICATION_JSON_TYPE)
.header(HttpHeaderField.OPENAM_USERNAME, username)
.header(HttpHeaderField.OPENAM_PASSWORD, password)
.post(Entity.json(null));
}
然后@Spy你的被测试类并模拟该方法以返回你想要的响应:
@Spy
ClassUnderTest classUnderTest;
@Mock
Response responseMock;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void test(){
doReturn(responseMock).when(classUnderTest).buildResponse();
// Act
classUnderTest.login(login,pass);
// Assertions
}