Spock使用Spy来Mock内部调用的方法
使用Spy来Mock内部调用的方法
如果使用Spy不生效参考
使用前先看看哪些场景不生效,避免浪费太多时间,我曾经就是mock一个方法折腾两个小时都没弄出来,后来问了 小美智能助理 ,告诉我其中private修饰的方法不生效..我把private改成protected
修饰之后, 再次重启单测,立马就好使了.
https://blog.csdn.net/qq_41489540/article/details/139861513
示例
在Spock框架中,要mock一个类中调用的另一个方法,通常需要使用Spock的Spy功能。Spy允许你在一个实例上部分地mock方法,这意味着你可以选择性地mock某些方法,而其他方法则保持原有行为。以下是如何使用Spy来mock内部方法调用的步骤:
示例代码
假设你有一个Calculator
类,它有一个calculate
方法,这个方法内部调用了add
方法。你想要mock掉add
方法。
class Calculator {
int calculate(int a, int b) {
return add(a, b)
}
// 内部调用的方法
private int add(int a, int b) {
return a + b
}
}
class CalculatorSpec extends Specification {
def "should mock internal add method"() {
given:
def calculator = Spy(Calculator)
when:
// 正常调用calculate方法
calculator.calculate(2, 3)
then:
// mock掉add方法,当它被调用时返回10
1 * calculator.add(2, 3) >> 10
// 验证calculate方法的结果被mock方法影响
calculator.calculate(2, 3) == 10
}
}
在这个例子中,我们首先创建了Calculator
类的一个Spy对象。然后,我们使用1 * calculator.add(2, 3) >> 10
这行代码来指定当add
方法被调用时,它应该返回10而不是执行实际的加法操作。最后,我们验证calculate
方法的结果是否如我们所模拟的那样返回了10。
注意事项
- 请注意,Spy通常用来mock非静态的实例方法。如果需要mock静态方法或构造函数,你可能需要其他技术或工具,如PowerMock。
- 当使用Spy时,确保只mock你需要改变行为的方法。如果你不小心mock了不应该mock的方法,可能会导致测试结果不可靠。
- 在使用Spy时,原始的方法逻辑不会被执行,除非你使用
GroovySpy
并指定callable
返回真实的方法调用。 - 在实际的测试场景中,如果一个方法的内部实现对于你的测试用例不是很重要,使用Spy可以帮助你集中精力在你关心的行为上。
使用Spock的Spy功能可以使你在测试过程中有效地控制类的内部行为,这对于只想测试类的一部分行为而不是整个类的行为时非常有用。
如果你想mock的内部调用的方法是void怎么办?
被mock的代码片段
public Map<String, Object> runFlow (Flow flow) {
try {
DagEngine<Map<String, Object>> engine = buildEngine(flow);
//假如说我想mock下面这个.这个是内部调用的方法,它是被上面实例化的engine去调用的.
engine.runAndWait(flow);
//......业务代码逻辑
return xxxxxxxxxxxx;
} catch (Exception e){
//xxxxx
} finally {
//xxxxx
}
}
mock代码示例
def "runFlow"() {
given:
DagEngine<Map<String, Object>> engineOriginal = new FlowEngineBuilder<Map<String, Object>>()
.setFlow(flow)
.setInputParams(inputParams)
.setEnvMap(envMap)
.setRunMode(runMode)
.setExecutor(Executors.newSingleThreadExecutor())
.build();
PromptFlowEngine promptFlowEngine = Spy(PromptFlowEngine.class)
DagEngine<Map<String, Object>> engine = Spy(engineOriginal)
promptFlowEngine.buildEngine(flow, inputParams, envMap, runMode) >> engine
engine.runAndWait(_) >> {}
when:
def flowResult = promptFlowEngine.runFlow(flow, inputParams, envMap, runMode)
then:
flowResult != null
}
promptFlowEngine.runFlow方法会调用到 engine.runAndWait ,我想mock engine.runAndWait, 但是它是void修饰的, 解决办法很简单,
就是先mock buildEngine()方法,让它返回 "DagEngine<Map<String, Object>> engine = Spy(engineOriginal)" 这个被Spy好的engine对象, 然后再 mock"engine.runAndWait(_) >> {}" ,注意,>>后面的 {} ,这个"{}" 里面留空,就代表是void返回值.
原文地址:https://blog.csdn.net/qq_41489540/article/details/139861463
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!