2013-05-29 53 views
13

我們將Spock測試與Spring的@ContextConfiguration結合起來,因此我們可以在Spring上下文中構建bean,然後使用Spock進行實際測試。我們希望向我們的春豆注入spock mock。對於Mockito有一個擴展,它允許你做這樣的事情:如何在規範類之外創建Spock mock?

<mockito:mock id="accountService" class="org.kubek2k.account.DefaultAccountService" /> 

然後引用這個模擬到其他春豆。似乎Spock沒有這樣的擴展。如果您知道如何在Specification類之外創建Mock,那麼再次構建它可能不會太費工夫。創建我意識到的Spock模擬的唯一方法是:

T Mock(Class<T> type) 

in Specification。 Spock中有沒有一些API可以創建Mocks,因此我不能在Spring類中創建Spock mock?

回答

6

在規範類之外創建模擬(並在另一個規範類中使用它們)目前不可行。這是一個開放的功能請求。實現它不應該太難,但是它需要對spock-core進行一些更改。至少,需要有一種手動將模擬對象附加到另一個spec實例的方法。也許,將基於用戶的模擬創建API移出MockingApi基類也是有意義的。

你應該能夠爲你包包含在當時的塊中的所有驗證碼一起返回true(因爲斯波克會認爲這是一種說法)的輔助方法的調用使用具有的Mockito斯波克,只要。類似then: mockito { /* mockito verifications go here */ }

+4

我坐在SpringOne Spock&testMvc sess並且它開始感覺很明顯,爲了混合一些被嘲笑的服務和一些由Spring配置的服務(例如爲了避免在測試之外具有集成邏輯),這個特性將非常有用。 –

+0

也許SpecificationMixin是我在找什麼? –

+0

我對'SpecificationMixin'不熟悉。作品中有一個拉動請求,允許外部建模模擬,並希望它會隨着下一個Spock版本發佈。 –

5

找到一個簡單的解決方法來在Spring應用程序中使用Spock模擬對象。在這裏我的Spring配置文件來使用一個模擬的basar豆:

@Configuration @Profile("mocking") 
class MockingContext { 
    @Bean Basar basar(){ new DelegatingBasar() } 
} 

class DelegatingBasar implements Basar { 
    @Delegate Basar delegate 
} 

在這裏,它創建了一個簡單的斯波克規範和使用mock:

@Autowired 
Basar basar 
Basar basarMock 

def setup() { 
    basarMock = Mock(Basar) 
    basar.delegate = basarMock; 
} 

def "create a new seller"(User seller) { 
    given: 
     basarMock.findAllUsers() >> [] 
    when: 
     go "/static/sellers.html" 
     waitFor { $("#newUser") } 
     $("#newUser").click() 
     waitFor { $("#basarNumber") } 
     $("#basarNumber").value(seller.basarNumber) 
     $("#name").value(seller.name) 
     $("#lastname").value(seller.lastname) 
     $("#email").value(seller.email) 
     $("#saveUser").click() 
     waitFor { $("#successfullCreated") } 
    then: 
     1 * basarMock.saveUser({ newUser -> 
      newUser.basarNumber == seller.basarNumber 
      newUser.name  == seller.name 
      newUser.lastname == seller.lastname 
      newUser.email  == seller.email 
     }) 
    where: 
     seller << [ new User(basarNumber: "100", name: "Christian", lastname: "", email: ""), 
        new User(basarNumber: "ABC", name: "",   lastname: "", email: "")] 
} 
+1

這是一個整潔的解決辦法:)。與此同時,我們已經轉向更輕量級的方法。我們試圖在單元測試中完全避開構建Spring上下文,並簡單地模擬出所有的依賴關係(請參閱https://gist.github.com/derkork/45d7fba64b54a41608e1)。這顯着提高了我們的測試吞吐量。我們只使用spring來處理像DAO測試這樣的複雜事情,我們會在內存數據庫中發射真實語句。 –

0

這是相當具有直接的「純春「:

def parentAppCtx = new StaticApplicationContext() 
parentAppCtx.beanFactory.registerSingleton("myBean", Mock(MyClass)) 
parentAppCtx.refresh() 
def appCtx = new ClassPathXmlApplicationContext("spring-config.xml", parentAppCtx) 

當然,假設你正在分解你的Spring配置。 (例如,如果你重新定義"myBean"spring-config.xml然後在spring-config.xml定義將被使用,因爲ApplicationContext本質上是一個地圖和最新的定義,把它會贏。)嘲笑的

1

建立一個規範的課外可能因爲Spock 1.1有DetachedMockFactorySpockMockFactoryBean。也支持基於XML配置的命名空間spock。你可以找到使用示例in the documentation

使用基於Java的配置和DetachedMockFactory一個Spring測試看起來是這樣的:

@ContextConfiguration(classes = [TestConfig, DiceConfig]) 
class DiceSpec extends Specification { 
    @Autowired 
    private RandomNumberGenerator randomNumberGenerator 

    @Subject 
    @Autowired 
    private Dice dice 

    def "uses the random number generator to generate results"() { 
     when: 
      dice.roll() 

     then: 
      1 * randomNumberGenerator.randomInt(6) 
    } 

    static class TestConfig { 
     private final mockFactory = new DetachedMockFactory() 

     @Bean 
     RandomNumberGenerator randomNumberGenerator() { 
      mockFactory.Mock(RandomNumberGenerator) 
     } 
    } 
} 

@Configuration 
class DiceConfig { 
    @Bean 
    Dice dice(RandomNumberGenerator randomNumberGenerator) { 
     new Dice(randomNumberGenerator) 
    } 
} 

和基於XML的配置是這樣的:

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:spock="http://www.spockframework.org/spring" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.spockframework.org/spring http://www.spockframework.org/spring/spock.xsd"> 
    <spock:mock id="randomNumberGenerator" class="RandomNumberGenerator"/> 
</beans> 

確保包括spock-spring依賴性:

testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4-rc-3'