0

grails 2.4.4 (および 2.4.5) を使用して、次の小さなアプリケーションを作成しました。

grails create-app example
cd example
grails create-domain-class Book

次に、 Book.groovy を次のように編集しました

package example
class Book {
    String title;
    static constraints = {
    }
}  

次に、基本的なコントローラーを追加しました

grails> create-controller example.book
| Created file grails-app/controllers/example/BookController.groovy
| Created file grails-app/views/book
| Created file test/unit/example/BookControllerSpec.groovy

コントローラーを変更して、RestfulController を拡張します。

package example
import grails.rest.*
class BookController extends RestfulController<Book> {
    static responseFormats=['json','xml']
    BookController() {
        super(Book)
    }
}

UrlMappings をフックして、書籍を /api/books のリソースとして提供します。

class UrlMappings {
  static mappings = {
    "/api/books"(resources: "book")
    "/"(view:"/index")
    "500"(view:'/error')
  }
}

最後に、BootStrap.groovy でいくつかの本を作成しました。

import example.*
class BootStrap {
    def init = { servletContext ->
        new Book(title: "Book 1").save(failOnError:true);
        new Book(title: "Book 2").save(failOnError:true);
        new Book(title: "Book 3").save(failOnError:true);
    }
    def destroy = {
    }
}

それからgrails run-app

そして、すべてが良さそうです。example.Book コントローラがインデックス ページに表示されます。3 つの本は、json または xml として表示できます。

それでは、単体テストに進みます。

BookControllerSpec を次のように編集します

package example
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification

@TestFor(BookController)
@Mock(Book)
class BookControllerSpec extends Specification {

    def setup() {
        new Book(title: "Unit Test Book 1").save(failOnError:true);
        new Book(title: "Unit Test Book 2").save(failOnError:true);
        new Book(title: "Unit Test Book 3").save(failOnError:true);
    }
    void "My Setup Worked"() {
        given: "My setup ran"
        when: "I ask for the count"
        then: "I should get back 3"
        Book.count() == 3;
    }

    void "I can access my Controller index method"() {
        given: "My setup ran"
        when:  "I call index"
        request.method="GET"
        response.format="xml"
        controller.index();

        then: "I get an XML object back with 3 books"
        println response.contentAsString
        response.xml.book*.title.size()==3
    }
}

最初のテストはパスし、2 番目のテストは失敗します。失敗したテストの println からの出力は、書籍の空の xml リストです。

<?xml version="1.0" encoding="UTF-8"?><list />

何が起こっているのかを調査しながら、親クラス (RestfulController) の index メソッドに注目しました。

そのメソッドを BookController にコピーすることで、単体テストがパスし始めます。

-- index メソッドをコピーした新しいバージョンの BookController --

package example
import grails.rest.*
class BookController extends RestfulController<Book> {
    static responseFormats=['json','xml']
    BookController() {
        super(Book)
    }

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond listAllResources(params), model: [("${resourceName}Count".toString()): countResources()]
    }
}

インデックス メソッドを BookController にコピーしなくても、RestfulController のインデックス メソッドを機能させるために、仕様に追加する必要があるものは他にありますか?

BookController から直接実行すると への呼び出しがlistAllResources機能するのに、RestfulController から実行すると行が返されない理由は何ですか。

上記の単体テストは、grails 2.3 用に書かれた Grails In Action ブックで説明されているその他の単体テストの修正版です。 http://www.manning.com/gsmith2/

4

1 に答える 1

0

単体テストは、grails を使用すると非常に扱いにくくなる場合があります。この失敗の原因を正確に突き止めることはできませんでしたが、別の奇妙な点を発見しました。

失敗したテストをスペック ファイルに 2 回挿入すると、1 回目は失敗しますが、2 回目は成功します。

void "first call to index doesn't work."() {
    given: "My setup ran"
    when:  "I call index"
    request.method="GET"
    response.format="xml"
    controller.index();

    then: "I get an XML object back with 3 books"
    println response.contentAsString
    response.xml.book*.title.size()==3
}

void "2nd call to index works"() {
    given: "My setup ran"
    when:  "I call index"
    request.method="GET"
    response.format="xml"
    controller.index();

    then: "I get an XML object back with 3 books"
    println response.contentAsString
    response.xml.book*.title.size()==3
}

Grails テスト フレームワークの奥深くにある何かが、最初に呼び出されたときにそのインデックス メソッドをうまく接続できません。

これ以上掘り下げる代わりに、これを統合テストとして書き直したところ、適切に動作し始めました。

grails 単体テストで無料で得られる多くの魔法がありますが、魔法が機能しない場合は、おそらく別のテスト フェーズを試す方がよいでしょう。

于 2015-09-16T22:07:49.783 に答える