使用JMockit进行模拟测试

3

我需要模拟一个类似于这样的Java类中的方法:

public class Helper{

    public static message(final String serviceUrl){   

        HttpClient httpclient = new HttpClient();
        HttpMethod httpmethod = new HttpMethod();

        // the below is the line that iam trying to mock
        String code = httpClient.executeMethod(method);

    }
}

我曾经尝试用Groovy编写junit,但是因为Groovy元编程技术不适用于Java类,所以无法实现。通过我的研究,我发现JMockit是一个很好的框架,可以模拟使用new构造函数创建的对象。

是否有人能够向我展示如何在Java或Groovy中编写上述类的单元测试。

提前致谢。

这是我迄今为止使用JMockit尝试过的测试案例,但没有成功。

void testSend(){

    def serviceUrl = properties.getProperty("PROP").toString()

    new Expectations(){
        {
            HttpClient httpClient=new HttpClient();
            httpClient.executeMethod(); returns null;
        }        
    };
    def responseXml = Helper.sendMessage(requestXml.toString(), serviceUrl)            
}

你尝试过使用JMockit吗?我知道你上一个问题中提到了JMockit,但还有Mockito和EasyMock可供选择。有很多示例可以参考,你尝试过哪些呢? - Dave Newton
我已经在我的问题中添加了一个编辑,展示了我编写的测试。由于我正在研究的模拟对象是httpClient,您认为使用Java还是Groovy编写测试用例更好? - Npa
3个回答

2

您的测试用例的Java版本应如下所示:

@Test
public void testSend() throws IOException {

    final String serviceUrl = "http://google.com/";

    new Expectations(){
        // these bits are important as they tell Jmockit what classes to mock
        @Mocked HttpClient client ;
        @Mocked GetMethod method;

        {
            HttpClient httpClient= new HttpClient() ;
            HttpMethod method = new GetMethod(withEqual(serviceUrl));
            try {
                httpClient.executeMethod(method);
            } catch (IOException e) {
                // not going to happen
            }
            result = 200;
        }
    };
    // run the test and assert something
    Assert.assertEquals(200, Helper.message(serviceUrl));
}

这个可以在github.com上找到,注意我使用了httpClient 3.1来实现你的消息方法,我猜这可能不完全正确,但足以回答问题。如果您能准备一个简单的grails项目并附上测试用例,我相信我可以找出问题所在。更新:我一直在本地玩具grails项目中尝试,并没有成功地配置jmockit。关键是要确保jmockit在类路径上位于junit之前,但由于junit已经包含在grails中,我找不到将jmockit放置在正确位置的方法。

谢谢回复。我该如何在我的Grails项目中开始使用Jmockit?我在Grails插件管理器中查找了Jmockit插件,但没有找到任何内容。 - Npa
这就是为什么一个简单的Grails项目设置方式与你的项目相同,会非常有用。在使用JMockit时,其中一个棘手的问题是类路径设置,具体来说,它需要在JUnit之前被设置在类路径上。 - Gareth Davis

2
使用jmockit,您还可以模拟实例创建。我更喜欢稍微不同的技术:
@Test    
public void testFoo(@Mocked final HttpClient client) {
       new Expectations() {{
              // expect instance creation and return mocked one
              new HttpClient(... );  returns(client)

              // expect invocations on this mocked instance
             client.invokeSomeMethid(); returns(something)
       }};


        helper.message(serviceUrl)
}

谢谢回复。我该如何在我的Grails项目中开始使用Jmockit?我在Grails插件管理器中查找了Jmockit插件,但没有找到任何内容。 - Npa
不知道Grails插件架构是如何工作的。但只要在测试工具之前的类路径上提供了JMockit,它就可以对带注释的类进行仪器化。JMockit专用列表可能是更好的信息来源。 - Konstantin Pribluda

0

感谢提出问题,使用Spring-web-3.2.2(它使用httpclient-4.0.1),我的代码如下:

    new NonStrictExpectations(){
        @Mocked(methods={"executeMethod"})
        ClientHttpRequest mocked_req;
        @Mocked(methods={"getBody"})
        ClientHttpResponse mocked_res;
        {
            byte[] buf  = (
            "<example_xml><person><name>Johnson</name><age>20</age></person></example_xml>" 
            ).getBytes();

            mocked_req.execute();
            mocked_res.getBody(); returns(new ByteArrayInputStream(buf));

        }
    };


    RestTemplate mytemplate = new RestTemplate();
    obj =         mytemplate.getForObject(.....);
    assertEquals("returned and parsed obj should be equal to this one", expectedObj, obj);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接