首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Spock模拟验证返回0次调用。

Spock模拟验证返回0次调用。
EN

Stack Overflow用户
提问于 2016-12-14 17:22:35
回答 1查看 5.5K关注 0票数 3

我正在开发一个Spring服务,它包含一个Camel处理器类,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
public class MyProc implements Processor {

    @Autowired
    private LogService logService;

    public void process(Exchange e) {
            // exchange object processing
            logService.update(e)
        }   
}

我有以下的史波克测试:

代码语言:javascript
代码运行次数:0
运行
复制
class MyProcTest extends Specification {
    @Shared def logService = Mock(LogService)
    @Shared def proc = new MyProc()

    def ctx = new DefaultCamelContext()
    def exch = new DefaultExchange(ctx)

    void setupSpec() {
        proc.logService = logService
    }

    def "log is updated when valid exchange is processed"() {
        given:
            exch.getIn().setBody(//xml string set on body)
        when:
            proc.process(exch)
        then: 
            1 * logService.update(_)
    }
}

当我运行它时,我会得到一个失败,对1* logService.update(_) (0调用)的调用太少。我试着调试代码,在MyProc中,语句被击中,当突出显示logService对象时(在Eclipse中)状态是‘LogService类型的mock,名为$spock_sharedField_logService',所以看起来模拟已经成功地注入到MyProc实例中。

我对Spock和Groovy很陌生,所以我可能遗漏了一些东西,但测试不应该通过吗?在运行测试时,将调用mocks方法,因此我不明白为什么测试报告根本没有调用mocks方法。我是否在MyProc实例上初始化模拟/设置模拟/不正确地设置交互?是否有我忽略的Groovy特性或警告?据我所知,Spock模拟在调用时将从方法返回一个默认值,这很好,我只想检查这个特定的方法是否已作为proc.process的一部分被调用,并具有一个有效的exchange对象。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-17 00:17:55

一个简单的答案是不要将@Shared用于模拟/存根/间谍。

代码语言:javascript
代码运行次数:0
运行
复制
@Shared def proc = new MyProcessor()

def test() {
    given:
    def log = Mock(LogService)
    proc.logService = log

    when:
    proc.process(new Object())

    then:
    1 * log.update(_)
}

现在解释一下:当您运行您的spec Spock时,它会为每个测试创建一个规范实例,另外,它还会创建一个共享规范实例来跟踪共享字段。

查看org.spockframework.runtime.BaseSpecRunner,您将看到两个字段:

代码语言:javascript
代码运行次数:0
运行
复制
protected Specification sharedInstance;
protected Specification currentInstance;

此外,还有两个规范上下文:共享和当前。上下文保存实例、模拟上下文和模拟控制器。问题来了。当您将模拟声明为shared时,它将绑定到共享模拟控制器,但是当您将declair交互(‘然后:’块)添加到当前模拟控制器中时,Spock将这些交互添加到当前的模拟控制器中。因此,当调用模拟方法(例如,logService.update(e))时,史波克检查共享模拟控制器是否允许这种交互,因为您将模拟声明为shared,但在那里找不到任何东西,因为您将交互放在当前控制器中。

不要使用模拟/存根/间谍作为@共享字段。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41148561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档