2015-11-02 97 views
3

如何重新使用spock mock中的闭包?spock可重复使用的闭包在模拟中

我可以输入关闭,因为它去(mock.sth({}关闭),但我怎么可以创建一个名为clsoure被重用或增加代码的可读性(mock.sth(hasStuffAsExpected))?

我有类:

class Link { 
    String url 
    boolean openInNewWindow 
} 

现在有服务

interface LinkService { 
    boolean checkStuff(Link link) 
} 

在我的测试,我想创造的东西是这样的:

@Shared def linkIsOpenInNewWindow = { Link l -> l.isOpenInNewWindow } 
@Shared Closure linkIsHttps = { Link l -> l.url.startsWith("https") } 

expect: 
    1 * linkService.checkStuff(linkIsHttps) >> true 
    1 * linkService.checkStuff(linkIsOpenInNewWindow) >> false 

当我运行此代码,它总是:

Too few invocations for: 

1 * linkService.checkStuff(linkIsHttps) >> true (0 invocations) 

Unmatched invocations (ordered by similarity): 

1 * linkService.checkStuff([email protected]) 

有没有什么办法来实现这一点,并创建和使用命名的可重复使用的斯波克封?

假规格:

@Grab('org.spockframework:spock-core:1.0-groovy-2.4') 
@Grab('cglib:cglib:3.1') 
@Grab('org.ow2.asm:asm-all:5.0.3') 

import spock.lang.Shared 
import spock.lang.Specification 

class Test extends Specification { 

    LinkService linkService = Mock(LinkService) 

    @Shared 
    Closure openInNewWindow = { it.isOpenInNewWindw()} 

    @Shared 
    def httpsLink = { Link l -> l.url.startsWith("https") } 

    @Shared 
    def secureLink = new Link(
     url: "https://exmaple.com", 
     openInNewWindw: false 
    ) 

    @Shared 
    def externalLink = new Link(
     url: "http://exmaple.com", 
     openInNewWindw: true 
    ) 

    def "failing closure test"() { 
     when: 
     def secureLinkResult = linkService.doStuff(secureLink) 
     def externalLinkResult = linkService.doStuff(externalLink) 

     then: 
     secureLinkResult == 1 
     externalLinkResult == 2 

     1 * linkService.doStuff(httpsLink) >> 1 
     1 * linkService.doStuff(openInNewWindow) >> 2 
    } 

    def "passing closure test"() { 
     when: 
     def secureLinkResult = linkService.doStuff(secureLink) 
     def externalLinkResult = linkService.doStuff(externalLink) 

     then: 
     secureLinkResult == 1 
     externalLinkResult == 2 

     1 * linkService.doStuff({Link l -> l.url.startsWith("https")}) >> 1 
     1 * linkService.doStuff({Link l -> l.openInNewWindw}) >> 2 
    } 
} 

class Link { 
    String url 
    boolean openInNewWindw 
} 

interface LinkService { 
    int doStuff(Link link) 
} 

回答

1

你可以这样写呀:

def "failing closure test"() { 
    when: 
    def secureLinkResult = linkService.doStuff(secureLink) 
    def externalLinkResult = linkService.doStuff(externalLink) 

    then: 
    secureLinkResult == 1 
    externalLinkResult == 2 

    1 * linkService.doStuff({ httpsLink(it) }) >> 1 
    1 * linkService.doStuff({ openInNewWindow(it) }) >> 2 
} 

一些解释可以发现in this thread

+0

都能跟得上。它不工作。关闭不被执行。 'def httpsLink = {Link l - > {print(“asd”);返回l.url.startsWith(“https”)}}' 并且不会打印asd文本。它看起来像关闭不执行 – daro

+0

为了使这个工作正常,你需要'1 * linkService.doStuff({httpsLink(it)})'不完全是我所希望的,但这是某事;) – daro

+0

我不知道为什么打印不起作用,但是当我将secureLink定义更改为应该打破测试的东西时(例如'url:“http://exmaple.com”'),则测试失败,但不打印任何东西。 –