7

我目前正在编写一些涉及 JMock 的测试。我无法理解代码的以下结构:

context.checking(new Expectations() {  //context is of type Mockery of course
            {
                allowing(csv).getFileName();
                will(returnValue(fileName));
            }
        });

慢慢分析,据我所知,

context.checking(new Expectations() { ... }

这将生成 的匿名实例化Expectations。但是为什么我们在这之后还有另一个括号,然后是一些奇怪的静态方法,例如allow() 等?如果有人能从 Java 的角度向我解释这里发生了什么,我将不胜感激。

4

3 回答 3

6

第二组大括号形成一个实例初始化块,编译器将其代码复制到该类的每个构造函数中。这使您可以访问实例成员。对于 JMock 的 API,它提供了一种初始化期望的简洁方法。您可以使用模板方法实现等效的事情(尽管在编译Expectations自身时会发出警告,说明从构造函数对可覆盖方法的不安全调用)。

public abstract class Expectations {
    public Expectations() {
        buildExpectations();
    }

    protected abstract void buildExpectations();

    ...
}

在你的测试中

context.checking(new Expectations() {
    protected void buildExpectations() {
        allowing(csv).getFileName();
        will(returnValue(fileName));
    }
});

我绝对更喜欢较短的版本。:)

于 2012-05-26T20:12:03.010 回答
6

实例初始化器很有趣。他们唯一真正看到他们经常使用的地方是 JMock。考虑一个更简单更易理解的上下文。您可以创建地图并向其中添加项目:

Map<String,String> map = new HashMap<String,String>(){
    {
        put("One","Something");
        put("Two","Other");
    }
};

也许这将帮助您了解 JMock 在做什么。

于 2012-05-26T20:12:45.143 回答
1

有些人认为在静态初始化器中创建期望值,使用静态方法提供了看起来很酷、简洁、流畅且易于阅读的语法来指定期望值——我同意他们的观点。笨拙的语法不仅在模拟框架中很酷 - 引擎盖下还有很多很酷的字节码操作。

于 2012-05-26T19:50:47.153 回答