出现obj1.getObj2(...).getYetAnotherObj().doSomething(...)
时可能需要mock多个对象。对于一个mock对象:
- Expectation中进行了record,则会返回record的result;
- 如果没有record,JMockit会自动创建一个返回被注解@Injectable的子对象
public class Dependency {
public CascadeDependency getCascadeDependency() {
//JMockit会拦截这个方法,返回一个非null对象
return null;
}
public CascadeDependency getAnotherCascadeDependency() {
//JMockit会拦截这个方法,返回一个非null对象
return null;
}
public String getString() {
//仍旧返回null
return null;
}
public Object getObject() {
//仍旧返回null
return null;
}
public List<Object> getList() {
//返回empty集合
return null;
}
}
@Test
public void TestMethod(@Mocked Dependency dependency) {
CascadeDependency first = dependency.getCascadeDependency();
CascadeDependency second = dependency.getCascadeDependency();
//调用另一个方法
CascadeDependency third = dependency.getAnotherCascadeDependency();
//所有都不会为null
assertNotNull(first);
assertNotNull(second);
assertNotNull(third);
//相同方法返回JMockit创建的同一个对象
assertSame(first, second);
//不同方法返回JMockit创建的同一个对象
assertNotSame(first, third);
//String返回null
assertNull(dependency.getString());
//Object返回null
assertNull(dependency.getObject());
//返回empty集合
assertNotNull(dependency.getList());
assertEquals(0, dependency.getList().size());
}
@Test
public void TestMethod(@Mocked Dependency dependency,
@Mocked CascadeDependency cascadeDependency) {
CascadeDependency first = dependency.getCascadeDependency();
CascadeDependency second = dependency.getAnotherCascadeDependency();
//因为子对象也@Mocked,所以会返回同一个对象
assertSame(first, second);
}
JMockit返回的非空对象实际上进行了@Injectable标识,所以:
@Test
public void TestMethod(@Mocked Dependency dependency) {
//虽然CascadeDependency没有出现在参数中,
//但是JMockit对其进行了@Injectable
//而由于没有在Expectation中record mockMethod的result,所以返回空
assertNull(dependency.getCascadeDependency().mockMethod());
//不影响CascadeDependency的其他实例
assertNotNull(new CascadeDependency().mockMethod());
}
也可以在Expectation中使用result指定返回对象,从而禁止JMockit自动生成。
@Test
public void TestMethod(@Mocked final Dependency dependency) {
//在Expectation中指定了返回结果,因此JMockit不会生成CascadeDependency
new NonStrictExpectations(){{
dependency.getCascadeDependency();
result = null;
result = new CascadeDependency();
}};
//第一次返回null
assertNull(dependency.getCascadeDependency());
//第二次返回新对象
assertNotNull(dependency.getCascadeDependency().mockMethod());
}
mock级联调用特别适合static factory,getCurrentInstance()
永远不会返回null。
@Test
public void TestMethod(@Mocked final Dependency dependency) {
assertSame(dependency, dependency.getCurrentInstance());
}
在Builder模式中也很方便验证,
@Test
public void createOSProcessToCopyTempFiles(@Mocked final ProcessBuilder pb) throws Exception{
Process copy = new ProcessBuilder().command(cmdLine).directory(wrkDir).inheritIO().start();
new Verifications() {{ pb.command(withSubstring("copy")).start(); }};
}