我在一些测试中使用Mockito.
我有以下课程:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
Run Code Online (Sandbox Code Playgroud)
我想只模拟第二个调用(super.save)ChildService.第一个调用必须调用真正的方法.有没有办法做到这一点?
jgo*_*ian 82
如果你真的没有重构的选择,你可以在超级方法调用中模拟/存根所有内容,例如
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
@Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
Run Code Online (Sandbox Code Playgroud)
iwe*_*ein 56
不,Mockito不支持这一点.
这可能不是您正在寻找的答案,但您所看到的是不应用设计原则的症状:
如果你提取策略而不是扩展超类,问题就会消失.
但是,如果您不允许更改代码,但无论如何您必须对其进行测试,并且以这种尴尬的方式,仍然存在希望.使用一些AOP工具(例如AspectJ),您可以将代码编织到超类方法中并完全避免执行(yuck).如果你使用代理,这不起作用,你必须使用字节码修改(加载时间编织或编译时间编织).还有一些模拟框架支持这种技巧,比如PowerMock和PowerMockito.
我建议你去重构,但如果这不是一个选项,那你就是为了一些严肃的黑客乐趣.
我找到了一种使用 PowerMockito 抑制超类方法的方法。为此需要 3 个简单的步骤
使用PowerMockito.suppress方法和MemberMatcher.methodsDeclaredIn方法来抑制父类方法
其次在@PrepareForTest中添加Parent类
使用 PowerMock 运行您的测试类,即在测试类上方添加@RunWith(PowerMockRunner.class) 。
@RunWith(PowerMockRunner.class)
@PrepareForTest({BaseService.class})
public class TestChildService(){
@Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
@Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Run Code Online (Sandbox Code Playgroud)
注意:只有当超类方法不返回任何内容时,这才有效。
小智 6
考虑将 ChildService.save() 方法的代码重构为不同的方法并测试该新方法而不是测试 ChildService.save(),这样您将避免对超级方法的不必要调用。
例子:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
96623 次 |
| 最近记录: |