2

我有以下结构

public class A{...}

public class B extends A{
    private C cObject;
    private Object otherValue;

    B(){
       cObject = new C(this);
    }
}

public class C{
    private B bObject;

    C(B bObject){
       this.bObject = bObject;
    }
}

我想测试 B 类的一个方法。我正在使用 mockito,因为我需要模拟 B 的另一个方法来测试我想要测试的方法。所以在我的测试中,我将 B 对象声明为@Spy,然后我调用MockitoAnnotations.initMocks(this);,最后我使用模拟方法doReturn().when().method();

现在我运行测试,它失败了。当我调试它时,我感到惊讶,我意识到当我在对象 B 中时,otherValue例如,该字段的值是,X但是当我在 C 中时,的值this.bObject.otherValue不是X但是null

由于我已经在 B 中创建了对象 C new C(this);,因此 B 和 C.bObject 不应该是同一个对象并因此包含相同的值吗?

注意:我也尝试过没有监视对象和模拟方法并且它可以工作,所以真正的问题是:

当我监视它时,Mockito 会用另一个对象替换我的对象吗?在那种情况下,我该怎么做才能让它发挥作用?

编辑一个更简单的解释可能是:我想测试一个对象 B,这个对象 B 创建一个对象 C 的实例,将自身(this)作为参数传递。我需要监视对象 B,因此我在测试中创建了一个 B 实例,然后调用MockitoAnnotations.initMocks(this);. 在此调用之后,两个对象(测试中的对象和 C 实例中的对象)是否仍然是同一个对象或 mockito 将其替换为新对象?

4

1 回答 1

2

B实例将在被窥探之前构建,因此C接收到的引用是实际 B对象而不是被窥探的实例。

您正在向间谍实例添加行为,该实例确实是与具有的对象不同的对象C.bObject,因此不应用该行为。同样的设置b.otherValue不会在b.cObject.bObject.otherValue被设置时产生。

您可以看到这些是不同的对象 - 假设存在默认值toString

final B b = Mockito.spy(new B());

System.out.println("spied: " + b);
System.out.println("b.cObject.bObject: " + b.cObject.bObject);

它应该产生以下内容:

spied: B$$EnhancerByMockitoWithCGLIB$$999ce15d@7a187814
b.cObject.bObject: B@5c73a7ab

也许您可以使用反射将b.cObject.bObject字段设置为间谍实例?例如:

final Field f = C.class.getDeclaredField("bObject");
f.setAccessible(true);
f.set(b.cObject, b);
于 2013-05-16T10:02:54.037 回答