从转换操作,Mockito,Java返回模拟

Seb*_*ien 1 java junit unit-testing mockito

我在这里尝试测试以下代码:

public class Something {
    public String doSomething(MyClass myClass) { 
        return Utils.getPresentationString(myClass)
    }
}

public class Utils{
    public static String getPresentationString(MyClass myClass) {
        if (myClass instanceof MySubClass) {
            MySubClass mySubClass = (MySubClass) myClass;
            return mySubClass.getMaskedPresentationString();
        } else {
            return myClass.getPresentationString();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

由于Utils是静态的,因此我在测试Something类时以黑盒方式对其进行了测试。

我试图让这行代码返回一个模拟:

MySubClass mySubClass = (MySubClass) myClass;
Run Code Online (Sandbox Code Playgroud)

所以我可以做

doReturn(MY_MASKED_STRING).when(this.mySubClassMock).getMaskedPresentationString()
Run Code Online (Sandbox Code Playgroud)

然后做

assertEquals(MY_MASKED_STRING, this.somethingUnderTest.doSomething(this.myClassMock))
Run Code Online (Sandbox Code Playgroud)

我该如何做这样的工作

doReturn(this.mySubClassMock).when(this.myClassMock).<<cast to MySubClass.class>>
Run Code Online (Sandbox Code Playgroud)

Gho*_*ica 5

该行是强制转换,它无法返回尚不存在的内容。但是之后。

public static String getPresentationString(MyClass myClass) {
    if (myClass instanceof MySubClass) {
Run Code Online (Sandbox Code Playgroud)

那只是进入该类的对象。

因此,您只需要:

MySubClass subclassMock = mock(MySubClass.class);
...

objectUnderTest.getPresentationString(subclassMock);
Run Code Online (Sandbox Code Playgroud)

然后,您的生产代码应该很高兴进入“它是instanceof”,然后进行强制转换,从而完全控制传入的对象。

但请注意:这里的“真正” OOP方法:避免使用instanceof / cast!

return mySubClass.getMaskedPresentationString();
... else
return myClass.getPresentationString()
Run Code Online (Sandbox Code Playgroud)

为什么您的SubClass不重写 getPresentationString(),以返回其他值?如果那是错误的,是否有可能有一些“基本”抽象方法然后具有两个实现?

长话短说:

  • 直接的答案是:根据要测试的路径,简单地输入mock(MyClass.class)or或mock(MySubClass.class)
  • 但更好的是:完全摆脱该实例/广播部分。好的OOP的全部要点就是要完全避免这种代码!