easymock 设置对模拟对象方法参数的期望

发布于 2024-11-17 13:09:04 字数 1593 浏览 4 评论 0原文

我不确定如何使用 easymock 设置这种行为。为了说明这一点,我创建了一个简化的示例。 基本上,我有一个返回 void 的方法,并获取一张地图,我希望 easymock 更改地图,删除我指定的条目。

假设我有以下接口:

public interface Filter{
    public void filter(Map<String,String>map);    

}

和以下类:

public class MyClass {
    private Filter filter;
    public MyClass(Filter filter) {
        this.filter = filter;
    }
    public Map<String,String> process(Map<String,String>map) {
       filter.filter(map);
       return map;
    }
}

我不知道如何设置此行为:

public class MyClassTest {

    /**
     * Test method for {@link easy.MyClass#process(java.util.Map)}.
     */
    @Test
    public void testProcess() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("one","AAA");
        map.put("remove","BBB");
        map.put("three","CCC");
        Map<String, String> expectedRet = new HashMap<String, String>();
        expectedRet.put("one","AAA");
        expectedRet.put("three","CCC");


        IMocksControl mockery = EasyMock.createControl();
        mockery.resetToStrict();
        mockery.checkOrder(true);

        Filter mockFilter = mockery.createMock("filter", Filter.class);
        MyClass m = new MyClass(mockFilter);
        mockFilter.filter(map);
        // I would like some behaviour that will remove the entry ("remove","BBB")
        // how can I define that?

        mockery.replay();
        m.process(map);        
        mockery.verify();

        assertEquals(expectedRet,map);

    }

}

I'm not sure how to set up this sort of behaviour with easymock. To illustrate I created a simplified example.
Basically, I have a method that returns void, and take one map, and I'd like easymock to change the map, deleting the entry that I specify.

Suppose I have the following interface:

public interface Filter{
    public void filter(Map<String,String>map);    

}

and the following class:

public class MyClass {
    private Filter filter;
    public MyClass(Filter filter) {
        this.filter = filter;
    }
    public Map<String,String> process(Map<String,String>map) {
       filter.filter(map);
       return map;
    }
}

I couldn't figure out how to set this behaviour:

public class MyClassTest {

    /**
     * Test method for {@link easy.MyClass#process(java.util.Map)}.
     */
    @Test
    public void testProcess() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("one","AAA");
        map.put("remove","BBB");
        map.put("three","CCC");
        Map<String, String> expectedRet = new HashMap<String, String>();
        expectedRet.put("one","AAA");
        expectedRet.put("three","CCC");


        IMocksControl mockery = EasyMock.createControl();
        mockery.resetToStrict();
        mockery.checkOrder(true);

        Filter mockFilter = mockery.createMock("filter", Filter.class);
        MyClass m = new MyClass(mockFilter);
        mockFilter.filter(map);
        // I would like some behaviour that will remove the entry ("remove","BBB")
        // how can I define that?

        mockery.replay();
        m.process(map);        
        mockery.verify();

        assertEquals(expectedRet,map);

    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

农村范ル 2024-11-24 13:09:04

您应该设置一个期望,即 m.process(map) 将在模拟的 Filter 上调用 filter(map)

    Filter mockFilter = mockery.createMock("filter", Filter.class);

    // set expectation
    mockFilter.filter(map);
    replay(mockFilter);

    MyClass m = new MyClass(mockFilter);
    m.process(map);

    // verify expectation
    verify(mockFilter);

您在上面的代码摘录中采用的路径正在尝试验证您的模拟过滤器。这不应该是您测试的目的。在您的案例中,被测试的类是 MyClass,而不是 Filter

更新:您可以向模拟添加行为:

expect(mockFilter.filter(map)).andDelegateTo(new Filter {
    @Override
    void filter(Map<String, String> map) {
        map.remove("remove");
    }
});

但是,在您的特定情况下,Filter 接口足够简单,导致 andDelegateTo 无法达到首先使用模拟Filter。使用相同数量的代码,您可以在测试中使用具体的 Filter 实例:

class TestFilter implements Filter {
    @Override
    void filter(Map<String, String> map) {
        map.remove("remove");
    }
}

MyClass m = new MyClass(new TestFilter());
m.process(map);
assertNull(map.get("remove"));

You should set an expectation that m.process(map) will call filter(map) on the mocked Filter:

    Filter mockFilter = mockery.createMock("filter", Filter.class);

    // set expectation
    mockFilter.filter(map);
    replay(mockFilter);

    MyClass m = new MyClass(mockFilter);
    m.process(map);

    // verify expectation
    verify(mockFilter);

The path you've taken in your code excerpt above is trying to verify your mocked filter. That shouldn't be the aim of your test. The class under test in your case is MyClass, not Filter.

Update: You can add behaviour to your mock:

expect(mockFilter.filter(map)).andDelegateTo(new Filter {
    @Override
    void filter(Map<String, String> map) {
        map.remove("remove");
    }
});

However, in your particular case the Filter interface is simple enough to cause andDelegateTo beat the purpose of using a mock Filter in the first place. With the same amount of code, you can use a concrete Filter instance in your test:

class TestFilter implements Filter {
    @Override
    void filter(Map<String, String> map) {
        map.remove("remove");
    }
}

MyClass m = new MyClass(new TestFilter());
m.process(map);
assertNull(map.get("remove"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文