使用Java + Mockito模拟Kotlin方法

时间:2017-07-03 01:16:52

标签: mocking mockito kotlin kotlin-interop

所以我只是为了好玩而将一个小的Java代码库迁移到Kotlin,并且我已经迁移了这个Java类:

public class Inputs {
    private String engineURL;
    private Map<String, String> parameters;

    public Inputs(String engineURL, Map<String, String> parameters) {
        this.engineURL = engineURL;
        this.parameters = parameters;
    }

    public String getEngineURL() {
        return engineURL;
    }

    public String getParameter(String key) {
        return parameters.get(key);
    }
}

进入这个Kotlin表示:

open class Inputs (val engineURL: String, 
                   private val parameters: Map<String, String>) {

    fun getParameter(key: String?): String {
        return parameters["$key"].orEmpty()
    }

}

但是现在我在用Java编写的现有测试套件上遇到了一些麻烦。更具体地说,我有这个使用Mockito的单元测试:

@Before
public void setupInputs() {
    inputs = mock(Inputs.class);
    when(inputs.getEngineURL()).thenReturn("http://example.com");
}

它在when行失败,说

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

有谁知道我怎么能做这个工作?我尝试在Kotlin版本上创建一个实际的getter(而不是依赖于隐式getter),但到目前为止没有运气。

非常感谢!

(如果你问自己为什么我开始使用生产代码而不是测试,或者为什么不使用mockito-kotlin,那么对这些问题没有真正的答案。就像我一样说,我只是为了好玩而迁移,并希望向我的团队中的其他开发人员展示在实际项目中实现语言之间的互操作性是多么容易)

更新:我注意到如果我将when(inputs.getParameter("key")).thenReturn("value")添加到同一个setupInputs()方法(在inputs.getEngineURL())调用之前),我最终会遇到NullPointerException Inputs#getParameter。 WTF?!

1 个答案:

答案 0 :(得分:1)

没关系,我通过重写Kotlin版本来逃避这两个错误消息:

open class TransformInputs (private val eURL: String, 
                            private val parameters: Map<String, String>) {

    open fun getParameter(key: String?): String {
        return parameters["$key"].orEmpty()
    }

    open fun getBookingEngineURL(): String {
        return eURL
    }

}