Mockito 如何监视模拟内部方法调用?
How does Mockito spy mock internal method calls?
我一直认为 Mockito 可以起到某种代理之类的作用。但现在我发现,Mockito 允许我做类似
的事情
class A {
public String m1() {
return m2();
}
public String m2() {
return "Hello";
}
}
class TestA {
public testM1() {
A a = Mockito.spy(A.class);
when(a.m2()).thenReturn("Bye");
Assert.assertEquals(a.m1(), "Bye");
}
}
这不适用于代理。它是怎么做到的?
该技术可用于允许调用内部 AOP 方法吗? (参见 Spring AOP not working for method call inside another method)
Mockito 可以使用代理,并且支持间谍。不过,您的语法有点不对:
/* BAD */ A a = Mockito.spy(A.class);
/* GOOD */ A a = Mockito.spy(new A());
不同行为的原因是 a
没有 将 委托给 spy()
的参数,而是将字段值复制到全新生成的 A 子类,其所有方法都被覆盖。因此,在 Spring 中,A 中对 this
的引用指的是未包装的实例,而在 Mockito 中,对 this
的引用指的是包装后的对象——包括对 [=13= 的隐式引用] 在 m2()
调用中 m1
.
虽然这听起来像是允许使用 AOP,但我无法测试它是否有效,并且相信这将取决于 Mockito 和 Spring AOP 的实现细节(以及包装发生的顺序)。
[社论:即使你能让两个代码生成系统很好地协同工作,你和你的同事是否能够read/understand/debug测试一个一年后? :)]
我一直认为 Mockito 可以起到某种代理之类的作用。但现在我发现,Mockito 允许我做类似
的事情class A {
public String m1() {
return m2();
}
public String m2() {
return "Hello";
}
}
class TestA {
public testM1() {
A a = Mockito.spy(A.class);
when(a.m2()).thenReturn("Bye");
Assert.assertEquals(a.m1(), "Bye");
}
}
这不适用于代理。它是怎么做到的? 该技术可用于允许调用内部 AOP 方法吗? (参见 Spring AOP not working for method call inside another method)
Mockito 可以使用代理,并且支持间谍。不过,您的语法有点不对:
/* BAD */ A a = Mockito.spy(A.class);
/* GOOD */ A a = Mockito.spy(new A());
不同行为的原因是 a
没有 将 委托给 spy()
的参数,而是将字段值复制到全新生成的 A 子类,其所有方法都被覆盖。因此,在 Spring 中,A 中对 this
的引用指的是未包装的实例,而在 Mockito 中,对 this
的引用指的是包装后的对象——包括对 [=13= 的隐式引用] 在 m2()
调用中 m1
.
虽然这听起来像是允许使用 AOP,但我无法测试它是否有效,并且相信这将取决于 Mockito 和 Spring AOP 的实现细节(以及包装发生的顺序)。
[社论:即使你能让两个代码生成系统很好地协同工作,你和你的同事是否能够read/understand/debug测试一个一年后? :)]