我有一个像
这样的课程public class Enclosing {
public String methodA() {
Inner.getContext();
......
}
private static class Inner{
// some context init
public static Context getContext() {
.....
}
}
}
现在我想测试methodA而不调用真正的Inner.getContext()。我一直在搜索,但找不到有效的解决方案。我正在使用Java 8.请帮助我吗?非常感谢
答案 0 :(得分:2)
您可以应用扩展和覆盖技术,这是它的工作原理。
鉴于此代码:
public class Enclosing {
public String methodA() {
Inner.getContext();
......
}
您可以将Inner.getContext()
来电转移到protected
方法:
public class Enclosing {
public String methodA() {
getContext();
......
}
protected void getContext() {
Inner.getContext();
......
}
然后在您的测试用例中,您可以扩展封闭类,并覆盖protected
方法以随意执行任何操作:
@Test
public void test_something() {
Enclosing enclosing = new Enclosing() {
@Override
protected void getContext() {
// do what you need here
}
};
// your test code on enclosing where you control getContext
}
答案 1 :(得分:1)
作为@janos'答案的替代方案,你可以注入一个策略(基本上,“偏好于继承的组合”方法):
interface ContextStrategy {
void getContext();
}
然后将此实例注入Enclosing
的构造函数:
class Enclosing {
private final ContextStrategy ctxStrategy;
Enclosing(ContextStrategy ctxStrategy) {
this.ctxStrategy = ctxStrategy;
}
String methodA() {
ctxStrategy.getContext();
// ...
}
}
然后为生产案例实现此接口,作为Enclosing
中的嵌套类:
static class ContextStrategyImpl implements ContextStrategy {
@Override public void getContext() {
Inner.getContext();
}
}
并为您的模拟案例实现替代版本。
答案 2 :(得分:0)
你应该不模拟一个private
类(无论它是像这里的嵌套类还是实际的内部类)。
相反,如果确实需要,则仅模拟Context
类型(否则,使用真正的Context
对象)。例如,下面显示了这样的测试,使用JMockit库:
@Test
public void mockingTheContext(@Mocked Context anyContext) {
new Expectations() {{
// record any method call results expected from "anyContext"
}};
new Enclosing().methodA();
new Verifications() {{
// verify calls to "anyContext", if applicable
}};
}
在上面的测试中,在嵌套类中创建Context
的事实是无关紧要的。通常,应始终避免使用模拟private
方法或类,因为它们只是实现细节。