Grails:集成测试在GORM集合上与NPE崩溃了吗?

时间:2015-08-27 14:41:55

标签: grails gorm integration-testing spock

我试图在控制器上进行相当简单的集成测试,虽然它在应用程序中都有效,但集成测试会因NPE而失败。我还是Grails 2.5.0 / Spock测试的新手,我确信我必须在这里做一些愚蠢的事情,但无法弄明白。我认为在集成测试中(与单元测试不同),行为应该与应用程序运行时的行为非常相似。

想象一下以下(非常简化)的场景来重现我遇到的问题。一个简单的3级域对象层次结构:

class Author {
    String name
    static hasMany = [books: Book]
}

class Book {
    String name
    static belongsTo = [author: Author]
    static hasMany = [chapters: Chapter]
}

class Chapter {
    String name
    static belongsTo = [book: Book]
}

一个控制器,只需一个动作即可接收单个作者拥有的所有书籍中的所有章节(即访问2个级别的集合):

class AuthorController {
    def listChapters(Long id) {
        Author a = Author.get(id)
        respond a.books.chapters.flatten()
    }
}

我在bootstrap中生成了示例数据,上面的控制器方法可以工作,并返回单个作者在平面的1级JSON数组中所有书籍的所有章节(如预期的那样)。但集成测试与NPE崩溃,好像从未初始化了延迟加载的集合,即Cannot get property 'chapters' on null object

以下是测试:

class AuthorIntegrationSpec extends IntegrationSpec {
    def controller

    def setup() {
        controller = new AuthorController()
    }

    def cleanup() {
        controller = null
    }

    def "chapters of a single author can be retrieved"() {
        when: "I call the listChapters action"
        controller.response.format = 'json'
        controller.request.method = 'GET'
        controller.params.id = 1
        controller.listChapters()

        then: "I get 200 OK"
        controller.response.status == 200
    }
}

我确定我必须遗漏一些非常明显的东西,但已经花费了3个小时就无济于事。我会很感激为什么会崩溃,或者我的方式与此集成测试完全错误?

更新:此处带有样本数据的BootStrap代码:

def init = { servletContext ->
    def rado = new Author(name: 'Rado').save(flush:true)
    def joe = new Author(name: 'Joe').save(flush:true)

    def book1 = new Book(name: 'Book1', author: rado).save(flush:true)
    def book2 = new Book(name: 'Book2', author: rado).save(flush:true)
    def book3 = new Book(name: 'Book3', author: rado).save(flush:true)
    def book4 = new Book(name: 'Book4', author: joe).save(flush:true)

    new Chapter(name: 'Chapter 1', book: book1).save(flush:true)
    new Chapter(name: 'Chapter 2', book: book1).save(flush:true)
    new Chapter(name: 'Chapter 3', book: book1).save(flush:true)
    new Chapter(name: 'Chapter 4', book: book1).save(flush:true)

    new Chapter(name: 'BChapter 1', book: book2).save(flush:true)
    new Chapter(name: 'BChapter 2', book: book2).save(flush:true)
}

0 个答案:

没有答案