java - Mockito 有没有办法从内部类运行监视对象的 stub 方法?

标签 java junit mockito inner-classes

我正在使用 Mockito 为其他人实现的代码编写 junit 测试。 简化:

  • 有一个外部类和一​​个内部类
  • 外部类保留内部类的实例。
  • 内部类使用外部类的方法。

简化的代码可能如下所示:

public class Outer {
    private Inner inner;

    public Outer(){
         inner=new Inner();
    }

    public Inner getInner(){
        return inner;
    }

    public String getOuterName(){
        return "outer";
    }

    public String getOuterNiceName(){
        return "name="+getOuterName();
    }

    public class Inner {
        public String getInnerName(){
            return getOuterName()+"-inner";     
        }
    }
}

我想对外部类的 getOuterName() 方法进行 stub ,以返回一个方便测试的值。 为此,我要“监视”该对象:

Outer outer=new Outer();
Outer spyOuter=spy(outer);
doReturn("outerspied").when(spyOuter).getOuterName();

现在,如果我打电话:

spyOuter.getObjectName(); 
spyOuter.getOuterNiceName(); 

在两次调用中都会调用 stub 方法,并且我得到字符串:“outerspied” 和“name=outerspied”

但是如果我打电话:

spyOuter.getInner().getInnerName(); 

在这种情况下,不会调用 stub 方法,而是调用原始方法。我期望“outerspied-inner”,但得到“outer-inner”

总而言之,在监视的外部对象中,引用“this”指向监视的实例。 但对于内部对象,对“Outer.this”的引用指向“非 spy ”实例。

我不知道我是否做错了什么,这是一个错误,还是它按设计工作;问题是:有解决方法吗?

提前非常感谢

最佳答案

I spy 仅使用代理包围被监视的对象。它没有任何机制来替换监视对象内的调用。因此,即使一个方法是通过 spy stub 的,如果 spy 对象直接调用该方法,则将调用 spy 对象的方法,而不是 spy 的 stub 。这基本上正是您的 Inner/Outter 所发生的情况。如果 Inner 未使用 Outterthis 实例,您也许可以使用反射来替换 Inner's 的引用外部。但由于 Inner 是一个实例内部类(而不是静态),并且由于 getOutterName 的调用使用隐式 Outter.this,因此您不需要有一个机制可以覆盖它。

关于java - Mockito 有没有办法从内部类运行监视对象的 stub 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22638583/

相关文章:

java - Spring获取响应作为对象转换的json

java - 如何断言断言的数量(或强制所有成员都已在断言中进行测试的其他方式)?

java - 如何模拟父类的 protected 方法?

eclipse - 使用Gradle构建从Eclipse运行JUnit测试时的类路径问题

java - 使用 JUnit 将 Collection#unmodifiableCollection 与 Java 中的 Collection#singletonList 进行比较

java - SLF4J:加载类 "org.slf4j.impl.StaticLoggerBinder"失败。运行 JUnit 测试时

android - 在测试期间使用 Mockito 模拟我类的一种方法

java - 如何在 Grizzly http 服务器中为 Jersey 设置模板基本路径?

java - 什么会导致 Eclipse 在调试时难以切换到正确的文件和行号

java - 如何在 Java 中指定(给出实际名称)XML 字段 (Apache CXF)