我想写一个Junit测试用例,测试else {id = null;}语句。我想做的是看看网站是活的,如果它是然后生成一个ID,但如果它不是活的(或下降了一点)返回ID为空。
public static String createID() {
String id = null;
HttpURLConnection connection = accessProv();
if (checkConfigs()) {
try {
if(checkSiteResponse(connection)) {
id = generateID(connection);
} else {
//test this statement
id = null;
}
} catch (IOException e) {
LOG.error("IOException");
}
} else {
id = generateRandomID();
}
return id;
}
public static boolean checkConfigs() {
return (stormConf != null && (boolean)stormConf.get(ENABLE_ID_REGISTRATION) && !((boolean)stormConf.get(SUBMIT_TOPOLOGY_LOCALLY)));
public static HttpURLConnection accessProv() {
HttpURLConnection connection = null;
try {
URL url = new URL(PROV_CREATE_ID_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int code = connection.getResponseCode();
} catch (IOException e) {
LOG.error("IOException");
}
return connection;
}
public static boolean checkSiteResponse(HttpURLConnection connection) throws IOException {
Boolean response;
if (connection.getResponseCode() == 200) {
response = true;
} else { response = false; }
return response;
}
我已经用Mockito编写了下面的测试用例:
@Test
public void testRequestError() throws ParseException, IOException {
HttpURLConnection mockHttpConnection = Mockito.mock(HttpURLConnection.class);
ProvenanceUtils provenanceUtils = Mockito.mock(ProvenanceUtils.class);
provenanceUtils.checkSiteResponse(mockHttpConnection);
when(provenanceUtils.checkConfigs()).thenReturn(true);
when(provenanceUtils.accessProvenance().getResponseCode()).thenReturn(100);
System.out.println(provenanceUtils.createID());
但是我得到错误:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Boolean cannot be returned by getResponseCode()
getResponseCode() should return int
我是Mockito的新手,不知道如何将getResponseCode
设置为200以外的东西。我在第一个when语句((when(provenanceUtils.checkConfigs()).thenReturn(true);
)中得到错误。
基本上我想要checkConfigs()
返回真和checkSiteResponse(connection)
返回假。Mockito有办法做到这一点吗?我想尽量避免使用PowerMock。
请记住,静态方法不能用Mockito模拟,除非使用PowerMockito。
除此之外,方法accessProvenance()返回的不是mock(是一个实际的HttpURLConnection实例),因此mockito不能修改它的行为。
你可以尝试使用WireMock模拟http请求
@Rule
public WireMockRule wireMockRule = new WireMockRule();
...
public void testRequestError() throws ParseException, IOException {
stubFor(post(urlEqualTo(PROV_CREATE_ID_URL))
.willReturn(aResponse()
.withStatus(100)));
...
}
问题是你把太多的职责推到一个类中。
示例:您有一个静态方法checkConfigs()。如果你用
来替换它interface ConfigurationChecker() {
boolean isConfigurationValid();
..
class ConfigurationCheckerImpl implements ...
然后,测试中的类包含一个类型为ConfigurationChecker的字段;你使用依赖注入(这样你的单元测试就可以把一个模拟的 ConfigurationChecker推到你的测试类中)…突然之间,您获得了对影响方法行为的元素的完全控制。
换句话说:您现在编写的代码只是难以进行测试。所有你需要控制的元素;不能(容易地)被测试代码访问。
你可以使用Powermock/mockito来测试它…或者你退一步,学习如何编写易于测试的代码(例如通过观看这个);重新设计……并最终得到A)更好的设计B)完全可测试的(没有"讨厌的"变通方法)。