使用Mockito更改方法中方法的值



我想写一个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)完全可测试的(没有"讨厌的"变通方法)。

相关内容

  • 没有找到相关文章

最新更新