更好的文章.
spring跨层mock,并且验证被mock的函数的实参. 传递的是bean
Jmockit使用详解之Mocking 官方翻译
<dependency>
<groupId>com.googlecode.jmockit</groupId><artifactId>jmockit</artifactId>
<version>1.5</version>
<scope>test</scope>
</dependency>
现在jmockit已经转入
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.19</version>
</dependency>
spring业务系统一般使用单例. 多层调用. 多层 mock
例如 A调用B,B调用C.
要测试A的方法,需要夸多层mock C的方法.
使用jmockit的NonStrictExpectations
@Service
public class A {
@Autowired
B b;
public void method() {
b.method();
}
}
@Service
public class B {
@Autowired
IC c;
public void method() {
System.out.println("b=" + c.method());
}
}
@Service
public class C implements IC {
@Override
public Integer method() {
System.out.println("123");
return 1;
}
}
public interface IC {
public Integer method();
}
官网文档 mocking
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class })
public class JmockitTestMock {
@Autowired
A a;
// 对接口进行mock,对应dubbo
@Autowired
IC ic;
// 夸层 mock.直接把该ic的object引用替换了
@Test
public void testMockit() {
new NonStrictExpectations(ic) {
{
ic.method();
//可以对输入进行解析,不同的输入不同的返回.
result = Integer.valueOf(5); }
};
a.method();
}
}
也可以对静态方法进行mock
new NonStrictExpectations(DynamicSettingsUtil.class) {
{
DynamicSettingsUtil.getString(anyString, anyString);
result = "123";
}
};
如果(ic)没有传入
new NonStrictExpectations(\) {
{
ic.method();
result = Integer.valueOf(5);
}
};
会报如下错误:
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter
方法二:
官网文档 Fake methods and fake classeshttp://jmockit.org/tutorial/Faking.html
new MockUp<C>() {
@Mock
public Integer method() {
//可以对输入进行解析,不同的输入不同的返回.
System.out.println("MockUp<C> return 6");
return 6;
}
};
ps: 没有没有@mock, 不会被mock.
方法二,比较智能,即使你获取不到实例. 直接把整个jvm内的class替换掉. 一了百了.
注: 如果遇到执行挺不下来的情况, 死循环的征兆 . 看看 jmockit的classPath顺序是不是比junit后面,如果后面.前把classPath顺序放到前面去.