【问题标题】:spock test with metaclass.render使用 metaclass.render 进行 spock 测试
【发布时间】:2023-03-11 10:40:01
【问题描述】:

为了在渲染(模板)中进行模型的集成测试,我使用 metaClass.render 将模型存储在地图中。但是,该地图似乎不适用于 'where' 块

def renderMap
def mmc

def setup() {
    MilestonesMgtController.metaClass.render = { Map map ->
        renderMap = map
    }
    mmc = new MilestonesMgtController()
}

void "create a new milestone"() {
    when:
    mmc.params.newName = 'Written Workshop'
    mmc.params.newDeadlineFT = a
    mmc.params.newDeadlinePT = '4'
    mmc.params.newNotificationFT = '7'
    mmc.params.newNotificationPT = '7'
    mmc.newMilestone()

    then:
    renderMap.template == 'milestoneDetails'
    renderMap.model.errorMessages == b

    where:
    a    |  b
    '4'  |  null                      //first test
    '0'  |  'deadlineFT cannot be 0'  //second test
}

'where' 块中的第二个测试失败,它说 renderMap 为空。如果我改变第一次和第二次测试之间的顺序,结果是一样的。第一轮之后,renderMap 似乎为空。你知道代码有什么问题吗?非常感谢!

【问题讨论】:

  • 为什么需要在集成测试中模拟render?集成规范不适用于此目的。
  • 虽然我同意这通常不是可行的方法,但在某些情况下需要对控制器进行集成测试。我们曾经能够使用 GroovyPagesTestCase 基类来处理渲染案例,但是在 Grails 2.3 切换到新的 @TestMixin 集成路由之后,它并没有真正被我所知道的任何东西所取代。我想您可能会争辩说,您想在控制器中进行集成测试的任何内容都应该移至服务并进行模拟。
  • @dmahapatro 抱歉,我对 Grails/Groovy 不熟悉,我两周前开始使用它。也许您可以为我指出一个正确的方法。我想用模板测试模型渲染,所以正如你在我之前的帖子中建议的那样,我使用了 Views[] 的单元测试。但是我的控制器必须从数据库中查询并且还使用服务。这就是我回到集成测试的原因。
  • 在单元测试中使用模拟数据和模拟服务是否有问题?
  • @dmahapatro 当我通过 mockDomain([...]).save 使用 mocke 数据时,返回的数据总是 [xxx:unsaved]

标签: grails groovy spock


【解决方案1】:

如果您在集成测试中开始类级别元分类,您真的会自食其果。与单元测试不同,这些元类更改不会被回滚,并且会感染您的测试运行被元类污染。

如果您确实需要集成测试,请尝试对控制器实例进行元分类以防止污染。我很好奇这是否能解决你的问题。此外,我倾向于在这种情况下使用@Shared,尽管我不确定它是否绝对必要。

@Shared renderMap
@Shared mmc

def setup() {
    mmc = new MilestonesMgtController()
    mmc.metaClass.render = { Map map -> renderMap = map }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2014-08-15
    • 1970-01-01
    • 2013-01-21
    相关资源
    最近更新 更多