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

时间:2016-08-14 17:24:50

标签: java junit mockito

我想写一个测试else的Junit测试用例{id = null;在下面的代码中的语句。我想要做的是查看该网站是否是实时的,如果它是生成一个ID,但如果它不是活的(或者有点下降)将id返回为null。

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(provenanceUtils.checkConfigs()).thenReturn(true);时出现错误。

基本上我希望checkConfigs()返回true,checkSiteResponse(connection)返回false。 Mockito有办法做到这一点吗?如果我可以提供帮助,我想避免使用PowerMock。

2 个答案:

答案 0 :(得分:1)

除非您使用static methods can not be mocked with 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)));
...
}

答案 1 :(得分:0)

问题在于你将太多的责任推到了一个班级。

示例:您有一个静态方法checkConfigs()。如果你用

之类的东西替换它
\\

然后,您的测试类包含ConfigurationChecker类型的字段;并且你使用依赖注入(这样你的单元测试可以将模拟的 ConfigurationChecker推送到你正在测试的类中)...突然之间,你获得了完全控制影响方法行为的元素。

换句话说:您现在编写的代码只需即可进行测试。您需要控制的所有元素;根本不能(轻松)访问测试代码。

你可以使用Powermock / mockito来测试它......或者你退后一步,学习如何编写容易测试的代码(例如,通过观察this);重做你的设计...并最终得到的东西是A)更好的设计B)完全可测试(没有“令人讨厌的”解决方法)。