2016-12-14 33 views
1

IM在包含骆驼处理器类,如下一个春天启动Java服务工作:斯波克模拟验证返回0调用

public class MyProc implements Processor { 

    @Autowired 
    private LogService logService; 

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

而且我有以下斯波克测试:

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 invocations)的调用太少。我试着调试代码,并在MyProc的,语句被击中,并强调(在Eclipse)的状态,所以它看起来像模拟“名为$ spock_sharedField_logService型LogService模拟”当logService对象已成功注入MyProc的实例。

进出口新的斯波克和常规所以我可能失去了一些东西,但不应该thetest通过? mocks方法在测试运行时被调用,所以我不明白为什么测试报告说mocks方法根本没有被调用。我初始化模拟/设置MyProc实例上的模拟/错误地设置交互?是否有一些Groovy功能或我错过的警告?据我了解,斯波克嘲笑将从调用时的方法,这是罚款,返回一个默认值,我只是想确认这个特殊的方法已被称为一个有效的交流对象

+1

作为一般的笔记,现场注射有问题 - 使用构造器注入只要有可能。 – chrylis

+1

如果删除'@ Shared',会发生什么情况?它看起来像是一次实例化模拟*(通常每个方法重置它),但每次重构上下文。这种不匹配可能会导致问题。 – chrylis

+0

删除共享和交换排尿设置()VS setupSpec工作,感谢 – jbailie1991

回答

3

一个proc.process的一部分简单的答案是不要使用@Shared来模拟/存根/间谍。

@Shared def proc = new MyProcessor() 

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

    when: 
    proc.process(new Object()) 

    then: 
    1 * log.update(_) 
} 

现在的解释: 当您运行规范斯波克为每个测试创建一个规范的实例,再加上,它会创建一个共享的规范实例来跟踪共享领域。

查找到org.spockframework.runtime.BaseSpecRunner,你会看到两个字段:

protected Specification sharedInstance; 
protected Specification currentInstance; 

此外,有两种规格上下文:共享和电流。上下文保持实例,模拟上下文和模拟控制器。这是问题所在。当你声明你的模拟为共享时,它绑定到共享模拟控制器,但是当你声明交互时('then:'block)Spock将这些交互添加到当前模拟控制器。因此,当调用模拟方法时(例如logService.update(e)),Spock会检查共享模拟控制器是否允许此交互,因为您声明模拟为共享,但在那里找不到任何内容,因为您将交互放置在当前控制器中。

不要使用模拟/存根/间谍为@Shared领域。

+0

或者至少* Spock * mocks。仍然有一些边缘情况(例如Spring上下文注入),您必须使用Mockito模拟。 *抽搐* – chrylis