java - 模拟 getClass()

标签 java unit-testing junit mocking mockito

在 Java 中,我想为方法编写测试(简化片段):

public class MyClass {
    private static final Set<Class> SOME_SET = new HashSet<Class>(Arrays.asList(Foo.class, Bar.class));

    public boolean isValid(Class clazz){
        return SOME_SET.contains(clazz);
    }
}

下面测试的问题

import static org.mockito.Mockito.when;
import org.mockito.Mockito;

public class MyClassTest {
    @Test
    public void isValid_Foo_returnsTrue(){
        Foo foo = Mockito.mock(Foo.class);
        MyClass target = new MyClass();
        assertTrue(target.isValid(foo));
   }
}

是在模拟类 Foo 上,foo.getClass() 返回带有附加后缀的类名。像这样:

Foo$$EnhancerByMockitoWithCGLIB$$45508b12

由于这个原因,测试失败,因为 SOME_SET.contains(clazz) 返回 false

我无法模拟 Foo 上的 getClass() 方法:

Mockito.when(foo.getClass()).thenReturn(Foo.class);

因为编译器在提示: OngoingStubbing) extends Foo>> 不适用于参数 (Class)

问题是,如何实现模拟对象的 getClass() 方法返回与真实(非模拟)对象的 getClass() 方法相同的值

最佳答案

Mockito.mock(Foo.class) 产生一个 Foo 类型的对象,但不完全是 Foo 类。在后台它会创建一个匿名代理,它是 Foo 的子类。所以,类(class)不一样。

关于您的 isValid 实现的一个注意事项是:您真的要检查类,还是只检查类的类型(也将接受子类,isAssignableFrom)。如果您检查类型匹配,那么您可以使用模拟类测试您的方法。

此外,您是否认为可以以某种方式处理对象而不是类(例如 isValid(object))?在我看来,在 OOP 中使用对象比 clazz 更好。 我建议:

    public boolean isValid(Object obj) {
        return SOME_SET.stream().anyMatch(clazz -> clazz.isInstance(obj));
    }

关于java - 模拟 getClass(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45409578/

相关文章:

java - 给一个arraylist另一个arraylist JAVA的值

java - 列表迭代 - 通用逻辑

python - 我的单元测试还应该测试第三方库/包功能吗?

java - 创建我自己的注释以扩展 JUnit4 行为

c - 是否有用于在 Apache C 模块上运行单元测试的框架?

java - 由于未找到 Junit 测试报告,Jenkins 构建失败 : Intern Framework

java - 随机测试用例失败 - Forked JVM 异常退出。

java - 如何根据 URL 创建 JWT 过滤器异常(exception)

java - JUnit 测试 if else 情况

java - Linux 上的 IntelliJ 使用错误的依赖版本