Spring 如何在规范类之外创建Spock模拟?

Spring 如何在规范类之外创建Spock模拟?,spring,unit-testing,spock,Spring,Unit Testing,Spock,我们将Spock测试与Spring的@ContextConfiguration结合起来,这样我们就可以在Spring上下文中构建bean,然后使用Spock进行实际测试。我们想把spock Mock注入我们的spring Bean。对于Mockito,有一个扩展,允许您执行以下操作: <mockito:mock id="accountService" class="org.kubek2k.account.DefaultAccountService" /> 然后将此模拟引用到其

我们将Spock测试与Spring的@ContextConfiguration结合起来,这样我们就可以在Spring上下文中构建bean,然后使用Spock进行实际测试。我们想把spock Mock注入我们的spring Bean。对于Mockito,有一个扩展,允许您执行以下操作:

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

然后将此模拟引用到其他SpringBean。斯波克似乎没有这样的扩展。然后,如果您知道如何在规范类之外创建模拟,那么构建这一模型可能不会花费太多的精力。我知道创建Spock模拟的唯一方法是:

T Mock(Class<T> type)   
T模拟(类类型)

在规格上。Spock中是否有一些API可以在不在Specification类中时创建Mock,这样我就可以为spring上下文创建Spock Mock?

当前不可能在spec类之外创建Mock(并在另一个spec类中使用它们)。这有一个开放的功能请求。实现这一点应该不会太难,但需要对spock core进行一些更改。至少,需要有一种方法将模拟对象手动附加到另一个规范实例。也许,将面向用户的mock创建API移出
MockingApi
基类也是有意义的


你应该能够使用McCito to斯波克,只要你将一个包含在一个BASE块中的所有验证代码都封装到一个帮助你返回<代码> Trime< /Cord>的帮助器方法(因为斯波克会认为它是一个断言)。类似于

then:mockito{/*mockito验证转到这里*/}

找到了在Spring应用程序中使用Spock mock对象的简单解决方法。下面是我的spring配置,用于对basar bean使用模拟:

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

class DelegatingBasar implements Basar {
  @Delegate Basar delegate
}
这里是一个简单的Spock规范,它创建并使用模拟:

@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: "")]
}
@Autowired
巴萨尔-巴萨尔
巴萨尔巴萨莫克
def设置(){
basarMock=模拟(Basar)
basar.delegate=basarMock;
}
def“创建新卖家”(用户卖家){
鉴于:
basarMock.findAllUsers()>>[]
什么时候:
转到“/static/sellers.html”
等待{$(“#新用户”)}
$(“#新用户”)。单击()
等待{$(“#basarNumber”)}
美元(“#basarNumber”).价值(卖方:basarNumber)
$(“#名称”).value(卖方名称)
$(“#lastname”).value(卖方.lastname)
$(“#email”).value(seller.email)
$(“#saveUser”)。单击()
等待{$(“#成功创建”)}
然后:
1*basarMock.saveUser({newUser->
newUser.basarNumber==seller.basarNumber
newUser.name==seller.name
newUser.lastname==seller.lastname
newUser.email==seller.email
})
哪里:

卖方这是非常直接的“纯弹簧”:


当然,这假设您正确地分解了Spring配置(例如,如果您在
Spring config.xml
中重新定义
“myBean”
,那么将使用
Spring config.xml
中的定义,因为
ApplicationContext
本质上是一个映射,其中最新的定义将获胜。)

可以在规范类之外创建模拟,因为还支持使用Spock 1.1和SpockMockFactory
和SpockMockFactoryBean
Spock
命名空间进行基于XML的配置。您可以找到使用示例

使用基于Java的配置和DetachedMockFactory的Spring测试如下所示:

@ContextConfiguration(类=[TestConfig,DiceConfig])
类规范扩展了规范{
@自动连线
专用随机数生成器随机数生成器
@主题
@自动连线
私人骰子
def“使用随机数生成器生成结果”(){
什么时候:
掷骰子
然后:
1*randomNumberGenerator.randomInt(6)
}
静态类TestConfig{
私有最终mockFactory=新的DetachedMockFactory()
@豆子
RandomNumberGenerator RandomNumberGenerator(){
mockFactory.Mock(RandomNumberGenerator)
}
}
}
@配置
类DiceConfig{
@豆子
骰子骰子(RandomNumberGenerator RandomNumberGenerator){
新骰子(randomNumberGenerator)
}
}
基于XML的配置如下所示:


确保包含
spock-spring
依赖项:

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

我坐在SpringOne Spock&testMvc会议上,开始感觉很明显,为了混合一些模拟服务和一些由Spring配置的服务(例如,为了避免在测试之外有集成逻辑)这项功能将非常有用。也许SpecificationMixin就是我要找的?我不熟悉
SpecificationMixin
。工程中有一个允许外部构造模拟的请求,希望它能与下一个Spock版本一起发布。@PeterNiederwieser-您可以分享给我们的任何链接更紧密地检查进展情况?这对于使用大量Spring的java大型商店来说是一个杀手级功能,可以更快地采用Spock。这是一个巧妙的解决方法:)。与此同时,我们转向了一种更轻量级的方法。我们试图在单元测试中完全避免构建Spring上下文,而只是模拟所有依赖项这大大提高了我们的测试吞吐量。我们只使用spring进行复杂的事情,比如DAO测试,在DAO测试中,我们针对内存中的数据库生成真实的语句。
testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4-rc-3'