(Quick Reference)

12 テスト - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith

Version: 2.3.0

Translated by: T.Yamamoto, Japanese Grails Doc Translating Team. Special thanks to NTT Software.
【注意】このドキュメントの内容はスナップショットバージョンを元に*意訳*されているため、一部現行バージョンでは未対応の機能もあります。

12 テスト

Automated testing is a key part of Grails. Hence, Grails provides many ways to making testing easier from low level unit testing to high level functional tests. This section details the different capabilities that Grails offers for testing.
自動化テストはGrailsにおいて重要な機能です。Grailsではユニットテストからファンクショナルテストまで、簡単にテスト生成できる様々な方法を提供しています。この章ではGrailsがテストのために提供している機能について詳しく説明します。

Grails 1.3.x and below used the grails.test.GrailsUnitTestCase class hierarchy for testing in a JUnit 3 style. Grails 2.0.x and above deprecates these test harnesses in favour of mixins that can be applied to a range of different kinds of tests (JUnit 3, Junit 4, Spock etc.) without subclassing
Grails 1.3.X以下のバージョンでは、JUnit 3スタイルのテストのためにgrails.test.GrailsUnitTestCaseのクラスを継承するようになっていましたが、Grails 2.0.X 以上のバージョンではサブクラスを作ることなく異なる種類のテスト(Junit 3, Junit4, Spock など)を実施可能なMixinsベースのテストを推奨しています。

The first thing to be aware of is that all of the create-* and generate-* commands create unit or integration tests automatically. For example if you run the create-controller command as follows:
まずはじめに全てのcreate-*generate-*のコマンドはunitもしくはintegrationテストを自動的に生成します。例えば、create-controllerコマンドを以下のように実行したとします。:

grails create-controller com.acme.app.simple

Grails will create a controller at grails-app/controllers/com/acme/app/SimpleController.groovy, and also a unit test at test/unit/com/acme/app/SimpleControllerTests.groovy. What Grails won't do however is populate the logic inside the test! That is left up to you.
Grailsはgrails-app/controllers/com/acme/app/SimpleController.groovyにコントローラを、test/unit/com/acme/app/SimpleControllerTests.groovyにユニットテストを作ります。しかしながら、Grailsはテストの中のロジックは作成しません!それはあなたに任されています。

The default class name suffix is Tests but as of Grails 1.2.2, the suffix of Test is also supported.
デフォルトのクラス名の最後にはTestsを付けます。しかし、Grails 1.2.2からはTestのサフィックスもサポートしています。

h4. Running Tests

テストの実行

Tests are run with the test-app command:
テストはtest-appコマンドにより実行されます。:

grails test-app

The command will produce output such as:
このコマンドは以下のような出力を行います。:

-------------------------------------------------------
Running Unit Tests…
Running test FooTests...FAILURE
Unit Tests Completed in 464ms …
-------------------------------------------------------

Tests failed: 0 errors, 1 failures

whilst showing the reason for each test failure.
それぞれのテストの失敗理由が表示されます。

You can force a clean before running tests by passing -clean to the test-app command.
test-appコマンドに-cleanを付与することにより、テスト実行前に強制的にテスト実行環境をクリーンにすることができます。

Grails writes both plain text and HTML test reports to the target/test-reports directory, along with the original XML files. The HTML reports are generally the best ones to look at.
Grailsはtarget/test-reportsディレクトリにオリジナルのXMLファイルとともにプレインテキストとHTMLのテストレポートの両方を出力します。最も見栄えがよいのはHTMLレポートです。

Using Grails' interactive mode confers some distinct advantages when executing tests. First, the tests will execute significantly faster on the second and subsequent runs. Second, a shortcut is available to open the HTML reports in your browser:
Grailsの対話モードをテスト実行時に使うことにはいくつかのメリットがあります。まず2回目以降のテスト実行が大幅に高速化されます。次にHTMLレポートをブラウザで開くショートカットが利用可能になります。:

open test-report

You can also run your unit tests from within most IDEs.
またほとんどのIDEでunitテストを実行できます。

h4. Targeting Tests

テストを指定する

You can selectively target the test(s) to be run in different ways. To run all tests for a controller named SimpleController you would run:
いくつかのやり方でテストを指定することができます。SimpleControllerと名付けられたコントローラの全てのテストを実行したい場合には以下のように指定します。:

grails test-app SimpleController

This will run any tests for the class named SimpleController. Wildcards can be used...
以下のコマンドはSimpleControllerという名前に対応する全てのテストを実行します。ワイルドカードを利用することも可能です。:

grails test-app *Controller

This will test all classes ending in Controller. Package names can optionally be specified...
以下はControllerでクラス名が終わる全てのクラスのテストを実行します。パッケージ名も指定可能です。

grails test-app some.org.*Controller

or to run all tests in a package...
この例では、パッケージ内の全てのテストを実行します。

grails test-app some.org.*

or to run all tests in a package including subpackages...
この例では、あるサブパッケージを含むパッケージの全てのテストを実行します。

grails test-app some.org.**.*

You can also target particular test methods...
特定のテストメソッドだけを指定することもできます。

grails test-app SimpleController.testLogin

This will run the testLogin test in the SimpleController tests. You can specify as many patterns in combination as you like...
以下のコマンドはSimpleControllerテストの中にあるtestLoginテストを実行します。いくつかのパターンを組合せて好きなように指定できます。

grails test-app some.org.* SimpleController.testLogin BookController

h4. Targeting Test Types and/or Phases

テスト種別とテストフェーズの条件によるテストの指定

In addition to targeting certain tests, you can also target test types and/or phases by using the phase:type syntax.
あるテストを指定するのに加えて、テストフェーズ:テスト種別の記法により テスト種別テストフェーズ を条件として指定できます。

Grails organises tests by phase and by type. A test phase relates to the state of the Grails application during the tests, and the type relates to the testing mechanism.

Grails comes with support for 4 test phases (unit, integration, functional and other) and JUnit test types for the unit and integration phases. These test types have the same name as the phase.

Testing plugins may provide new test phases or new test types for existing phases. Refer to the plugin documentation.

Grailsはテストフェーズとテスト種別によりテストを体系化しています。テストフェーズはGrailsアプリケーションにおけるどの状態のテストを行っているかを表しており、テスト種別はテストを行う機構に関連しています。

Grailsは4つのテストフェーズ(unit, integration, functionalそしてother)とunitintegrationの各テストフェーズに対応したJUnitのテスト種別をサポートしています。これらのテスト種別はそのテストフェーズと同じ名前になっています。

テストプラグインにより既存のテストフェーズに新しいテストフェーズもしくはテスト種別を追加することができます。詳しくはプラグインのドキュメントを参照してください。

To execute the JUnit integration tests you can run:
JUnitのintegrationテストを実行するには以下のように実行します:

grails test-app integration:integration

Both phase and type are optional. Their absence acts as a wildcard. The following command will run all test types in the unit phase:
テストフェーズテスト種別の指定は任意です。もし指定をしなかった場合には全てが該当します。以下のコマンドではunitテストフェーズの全てのテスト種別のテストを実行します。:

grails test-app unit:

The Grails Spock Plugin is one plugin that adds new test types to Grails. It adds a spock test type to the unit, integration and functional phases. To run all spock tests in all phases you would run the following:
Grails Spockプラグインプラグインを用いることでGrailsで新しいテスト種別が使えるようになります。spockテスト種別がunitintegrationそしてfunctionalテストフェーズで使えるようになります。全てのテストフェーズで全てのspockテストを実行するには次のように実行します。:

grails test-app :spock

To run the all of the spock tests in the functional phase you would run...
functionalフェーズの全てのspockテストを実行するには次のように実行します。

grails test-app functional:spock

More than one pattern can be specified...
1つ以上のテストパターンを指定できます。

grails test-app unit:spock integration:spock

h4. Targeting Tests in Types and/or Phases

テスト種別とテストフェーズを用いたテストの指定

Test and type/phase targetting can be applied at the same time:
名前によるテスト指定と、テスト種別やテストフェーズによるテスト指定は同時に適応可能です。:

grails test-app integration: unit: some.org.**.*

This would run all tests in the integration and unit phases that are in the package some.org or a subpackage.
この例では、some.orgのパッケージかサブパッケージの中でintegrationunitフェーズの全てのテストが実行されるでしょう。

12.1 ユニットテスト

Unit testing are tests at the "unit" level. In other words you are testing individual methods or blocks of code without consideration for surrounding infrastructure. Unit tests are typically run without the presence of physical resources that involve I/O such databases, socket connections or files. This is to ensure they run as quick as possible since quick feedback is important.

Unitテストは"単体"レベルのテストです。具体的には、環境周りを考慮せずに個々のメソッドやブロック単位で行うテストのことです。Unitテストは基本的にデータベース、ネットワーク接続、ファイルなどのI/Oを必要とする物理リソースを必要としません。素早いフィードバックを得られるように、Unitテストの実行時間はできる限り短くしてください。

The Test Mixins

テストMixin

Since Grails 2.0, a collection of unit testing mixins is provided by Grails that lets you enhance the behavior of a typical JUnit 3, JUnit 4 or Spock test. The following sections cover the usage of these mixins.

Grails 2.0以降、MixinのUnitテストライブラリがGrailsによって提供されており、代表的なJUnit 3、JUnit 4、Spockを使用したテストの実行をサポートします。以下の節では、Mixinの使い方について記載しています。

The previous JUnit 3-style GrailsUnitTestCase class hierarchy is still present in Grails for backwards compatibility, but is now deprecated. The previous documentation on the subject can be found in the Grails 1.3.x documentation

以前のGrailsUnitTestCaseクラスを継承するJUnit 3スタイルは、下位バージョンとの互換性のためにGrailsにまだ存在しています。しかし今は非推奨です。過去のドキュメントはGrails 1.3.x ドキュメンテーションで見つけることができます。

You won't normally have to import any of the testing classes because Grails does that for you. But if you find that your IDE for example can't find the classes, here they all are:

Grailsは自動でテストクラスをインポートするため、全てのテストクラスをインポートしなくても問題ありません。しかし、IDEでテストクラスを探せないことがあるかもしれないので、下記にそれらすべてのテストクラスを列挙します。

  • grails.test.mixin.TestFor
  • grails.test.mixin.TestMixin
  • grails.test.mixin.Mock
  • grails.test.mixin.support.GrailsUnitTestMixin
  • grails.test.mixin.domain.DomainClassUnitTestMixin
  • grails.test.mixin.services.ServiceUnitTestMixin
  • grails.test.mixin.web.ControllerUnitTestMixin
  • grails.test.mixin.web.FiltersUnitTestMixin
  • grails.test.mixin.web.GroovyPageUnitTestMixin
  • grails.test.mixin.web.UrlMappingsUnitTestMixin
  • grails.test.mixin.webflow/WebFlowUnitTestMixin

Note that you're only ever likely to use the first two explicitly. The rest are there for reference.
常に明示的に使うのは最初の2つのクラスだけであることに注意してください。残りはリファレンスのために列挙しています。

Test Mixin Basics

テストMixinの基本

Most testing can be achieved via the TestFor annotation in combination with the Mock annotation for mocking collaborators. For example, to test a controller and associated domains you would define the following:

ほとんどのテストは、モックを使用するためMockアノテーションとTestForアノテーションを組み合わせて使用します。例えば、コントローラーとドメインをテストするためには次のように定義します。

@TestFor(BookController)
@Mock([Book, Author, BookService])

The TestFor annotation defines the class under test and will automatically create a field for the type of class under test. For example in the above case a "controller" field will be present, however if TestFor was defined for a service a "service" field would be created and so on.

TestForアノテーションは、テスト対象のクラスを定義することで自動的にクラスタイプのフィールドを生成します。例えば、上記の場合、"controller"フィールドを生成します。また、もしTestForにサービスが定義されている場合、"service"フィールドが生成されます。

The Mock annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API. For those interactions that are not automatically mocked you can use the built in support for defining mocks and stubs programmatically. For example:

Mockアノテーションは複数の種類のモックを生成します。ほとんどのGORM APIの振る舞いをシミュレートするインメモリのGORM実装があります。自動でモック化されない振る舞いに対しては、ビルトインされているモック、スタブの作成機能が使用できます。例えば、次の通りです。

void testSearch() {
      def control = mockFor(SearchService)
      control.demand.searchWeb { String q -> ['mock results'] }
      control.demand.static.logResults { List results ->  }
      controller.searchService = control.createMock()
      controller.search()

assert controller.response.text.contains "Found 1 results" }

12.1.1 コントローラのユニットテスト

The Basics

基本

You use the grails.test.mixin.TestFor annotation to unit test controllers. Using TestFor in this manner activates the grails.test.mixin.web.ControllerUnitTestMixin and its associated API. For example:

コントローラUnitテストには、grails.test.mixin.TestForアノテーションを使用します。このようにTestForを使用することで、grails.test.mixin.web.ControllerUnitTestMixinとその関連APIが有効になります。

import grails.test.mixin.TestFor

@TestFor(SimpleController) class SimpleControllerTests { void testSomething() {

} }

Adding the TestFor annotation to a controller causes a new controller field to be automatically created for the controller under test.

TestForアノテーションにコントローラを追加することにより、controllerフィールドにテスト対象のコントローラが自動的に生成されます。

The TestFor annotation will also automatically annotate any public methods starting with "test" with JUnit 4's @Test annotation. If any of your test method don't start with "test" just add this manually

TestForアノテーションは"test"から始まるパブリックなメソッドに自動的にJUnit4のTestアノテーションを付与します。もしテストメソッドが"test"で始まらない場合はTestアノテーションを手動で付与してください。

To test the simplest "Hello World"-style example you can do the following:

最もシンプルなHello World形式のテストは次の通りです。

// Test class
class SimpleController {
    def hello() {
        render "hello"
    }
}

void testHello() {
    controller.hello()

assert response.text == 'hello' }

The response object is an instance of GrailsMockHttpServletResponse (from the package org.codehaus.groovy.grails.plugins.testing) which extends Spring's MockHttpServletResponse class and has a number of useful methods for inspecting the state of the response.

responseオブジェクトは、GrailsMockHttpServletResponseorg.codehaus.groovy.grails.plugins.testingパッケージに含まれている)のインスタンスです。SpringのMockHttpServletResponseクラスを継承しており、レスポンスの状態を調べる便利なメソッドを定義しています。

For example to test a redirect you can use the redirectedUrl property:

例えば、リダイレクトをテストするにはredirectedUrlプロパティを使用できます。

// Test class
class SimpleController {
    def index() {
        redirect action: 'hello'
    }
    …
}

void testIndex() {
    controller.index()

assert response.redirectedUrl == '/simple/hello' }

Many actions make use of the parameter data associated with the request. For example, the 'sort', 'max', and 'offset' parameters are quite common. Providing these in the test is as simple as adding appropriate values to a special params variable:

ほとんどのアクションはリクエストに設定されたパラメータを使用します。例えば、'sort'、'max'、'offset'といったパラメータが一般的です。これらのパラメータをテストで利用するにはparams変数に値を代入するだけで簡単に設定できます。

void testList() {
    params.sort = "name"
    params.max = 20
    params.offset = 0

controller.list() … }

You can even control what type of request the controller action sees by setting the method property of the mock request:

リクエストのmethodプロパティにリクエストタイプを設定することにより、リクエストタイプ毎のコントローラのアクションを確認できます。

void testSave() {
    request.method = "POST"
    controller.save()
    …
}

This is particularly important if your actions do different things depending on the type of the request. Finally, you can mark a request as AJAX like so:

リクエストタイプに応じてアクションが違った挙動をする場合、これは非常に重要です。さらに、次のようにAjaxとしてリクエストを作ることもできます。

void testGetPage() {
    request.method = "POST"
    request.makeAjaxRequest()
    controller.getPage()
    …
}

You only need to do this though if the code under test uses the xhr property on the request.

テスト対象コードのリクエストでxhrプロパティを使用してたとしても、これを実行するだけです。

Testing View Rendering

ビューのレンダリングテスト

To test view rendering you can inspect the state of the controller's modelAndView property (an instance of org.springframework.web.servlet.ModelAndView) or you can use the view and model properties provided by the mixin:

コントローラのmodelAndViewプロパティ(org.springframework.web.servlet.ModelAndViewのインスタンス)、または、Mixinで提供されているviewmodelプロパティを使用することにより、ビューのレンダリングをテストすることができます。

// Test class
class SimpleController {
    def home() {
        render view: "homePage", model: [title: "Hello World"]
    }
    …
}

void testIndex() {
    controller.home()

assert view == "/simple/homePage" assert model.title == "Hello World" }

Note that the view string is the absolute view path, so it starts with a '/' and will include path elements, such as the directory named after the action's controller.

viewの文字列は絶対パスであることに注意してください。これは、'/'から始まり、動作するコントローラの名前から決まるディレクトリ名などがパスとして含まれます。

Testing Template Rendering

テンプレートレンダリングテスト

Unlike view rendering, template rendering will actually attempt to write the template directly to the response rather than returning a ModelAndView hence it requires a different approach to testing.

テンプレートのレンダリングはModelAndViewを返すのではなく、レスポンスにテンプレートの内容を直接書き込みます。そのため、ビューのレンダリングとは異なるテストのアプローチが必要になります。

Consider the following controller action:

次のコントローラアクションを見てください。

class SimpleController {
    def display() {
        render template:"snippet"
    }
}

In this example the controller will look for a template in grails-app/views/simple/_snippet.gsp. You can test this as follows:

この例では、コントローラはgrails-app/views/simple/_snippet.gspにあるテンプレートを探します。そして、次のようにテストをします。

void testDisplay() {
    controller.display()
    assert response.text == 'contents of template'
}

However, you may not want to render the real template, but just test that is was rendered. In this case you can provide mock Groovy Pages:

テンプレートをレンダリングしたくない場合にも、テストでは実際にテンプレートがレンダリングされます。このような場合はGroovy Pagesのモックが使用できます。

void testDisplay() {
    views['/simple/_snippet.gsp'] = 'mock contents'
    controller.display()
    assert response.text == 'mock contents'
}

Testing Actions Which Return A Map

マップを返すアクションをテスト

When a controller action returns a java.util.Map that Map may be inspected directly to assert that it contains the expected data:

コントローラアクションがjava.util.Mapを返す場合は、Mapに期待したデータが含まれているか直接検証できます。

class SimpleController {
    def showBookDetails() {
        [title: 'The Nature Of Necessity', author: 'Alvin Plantinga']
    }
}

import grails.test.mixin.*

@TestFor(SimpleController) class SimpleControllerTests {

void testShowBookDetails() { def model = controller.showBookDetails()

assert model.author == 'Alvin Plantinga' } }

Testing XML and JSON Responses

XMLとJSONレスポンスのテスト

XML and JSON response are also written directly to the response. Grails' mocking capabilities provide some conveniences for testing XML and JSON response. For example consider the following action:

XMLとJSONのレスポンスもまた、直接レスポンスに書き込まれます。Grailsのモック機構は、XMLとJSONのレスポンスをテストするために便利な機能をいくつか提供しています。

def renderXml() {
    render(contentType:"text/xml") {
        book(title:"Great")
    }
}

This can be tested using the xml property of the response:

次の例は、レスポンスのxmlプロパティを使ってテストしています。

void testRenderXml() {
    controller.renderXml()
    assert "<book title='Great'/>" == response.text
    assert "Great" == response.xml.@title.text()
}

The xml property is a parsed result from Groovy's XmlSlurper class which is very convenient for parsing XML.

xmlプロパティは、XMLをパースするためにとても便利なGroovyのXmlSlurper でパースされた結果です。

Testing JSON responses is pretty similar, instead you use the json property:

jsonプロパティを使うだけで、JSONレスポンスのテストもかなり似ています。

// controller action
def renderJson() {
    render(contentType:"application/json") {
        book = "Great"
    }
}

// test
void testRenderJson() {

controller.renderJson()

assert '{"book":"Great"}' == response.text assert "Great" == response.json.book }

The json property is an instance of org.codehaus.groovy.grails.web.json.JSONElement which is a map-like structure that is useful for parsing JSON responses.

jsonプロパティは、JSONレスポンスをパースするために便利なorg.codehaus.groovy.grails.web.json.JSONElementのインスタンスでマップライクな構造をもっています。

Testing XML and JSON Requests

XMLとJSONリクエストのテスト

Grails provides various convenient ways to automatically parse incoming XML and JSON packets. For example you can bind incoming JSON or XML requests using Grails' data binding:

Grailsは、入力されるXMLとJSONパケットを自動的にパースするためのいろいろな便利な方法を提供しています。例えば、入力されるJSONかXMLリクエストをGrailsのデータバインディングを使ってバインドできます。

def consumeBook() {
    def b = new Book(params['book'])

render b.title }

To test this Grails provides an easy way to specify an XML or JSON packet via the xml or json properties. For example the above action can be tested by specifying a String containing the XML:

次のテストでは、xmljsonプロパティを用いてXMLやJSONリクエストを設定しています。例えば、上記のアクションはXMLの文字列を設定することによってテストができます。

void testConsumeBookXml() {
    request.xml = '<book><title>The Shining</title></book>'
    controller.consumeBook()

assert response.text == 'The Shining' }

Or alternatively a domain instance can be specified and it will be auto-converted into the appropriate XML request:

もしくは、ドメインインスタンスを設定することで、適切なXMLリクエストに自動変換してテストをします。

void testConsumeBookXml() {
    request.xml = new Book(title:"The Shining")
    controller.consumeBook()

assert response.text == 'The Shining' }

The same can be done for JSON requests:

JSONリクエストでも同じようにテストできます。

void testConsumeBookJson() {
    request.json = new Book(title:"The Shining")
    controller.consumeBook()

assert response.text == 'The Shining' }

If you prefer not to use Grails' data binding but instead manually parse the incoming XML or JSON that can be tested too. For example consider the controller action below:

もし、Grailsのデータバインディングを使用したくない場合は、入力されるXMLまたはJSONを手動でパースする必要がありますが、このような場合も同じようにテストできます。次のコントローラアクションを見てください。

def consume() {
    request.withFormat {
        xml {
            render request.XML.@title
        }
        json {
            render request.JSON.title
        }
    }
}

To test the XML request you can specify the XML as a string:

XMLリクエストをテストするためには、XMLの文字列を設定します。

void testConsumeXml() {
    request.xml = '<book title="The Stand" />'

controller.consume()

assert response.text == 'The Stand' }

And, of course, the same can be done for JSON:

もちろん、同じことがJSONでもできます。

void testConsumeJson() {
    request.json = '{title:"The Stand"}'
    controller.consume()

assert response.text == 'The Stand' }

Testing Spring Beans

Springビーンのテスト

When using TestFor only a subset of the Spring beans available to a running Grails application are available. If you wish to make additional beans available you can do so with the defineBeans method of GrailsUnitTestMixin:

TestForを使用した場合は、Grailsアプリケーションを実行するのに必要なSpringビーンのサブセットだけが利用できます。もし、利用できるビーンを追加したい場合は、GrailsUnitTestMixindefineBeansメソッドを使うことにより、ビーンを追加できます。

class SimpleController {
    SimpleService simpleService
    def hello() {
        render simpleService.sayHello()
    }
}

void testBeanWiring() {
    defineBeans {
        simpleService(SimpleService)
    }

controller.hello()

assert response.text == "Hello World" }

The controller is auto-wired by Spring just like in a running Grails application. Autowiring even occurs if you instantiate subsequent instances of the controller:

コントローラは実行中のGrailsアプリケーションのように、Springによって自動的にビーンが注入されます。もしコントローラを後でインスタンス化した場合も自動的に注入されます。

void testAutowiringViaNew() {
    defineBeans {
        simpleService(SimpleService)
    }

def controller1 = new SimpleController() def controller2 = new SimpleController()

assert controller1.simpleService != null assert controller2.simpleService != null }

Testing Mime Type Handling

MIME Typeの制御のテスト

You can test mime type handling and the withFormat method quite simply by setting the response's format attribute:

MIME Typeの制御とwithFormatメソッドは、レスポンスのformat属性を設定することにより簡単にテストができます。

// controller action
def sayHello() {
    def data = [Hello:"World"]
    withFormat {
        xml { render data as XML }
        html data
    }
}

// test
void testSayHello() {
    response.format = 'xml'
    controller.sayHello()

String expected = '<?xml version="1.0" encoding="UTF-8"?>' + '<map><entry key="Hello">World</entry></map>'

assert expected == response.text }

Testing Duplicate Form Submissions

フォームの2重送信テスト

Testing duplicate form submissions is a little bit more involved. For example if you have an action that handles a form such as:

フォームの2重送信のテストは少し複雑になります。例えば、次のようなフォームを処理するアクションがあるとします。

def handleForm() {
    withForm {
        render "Good"
    }.invalidToken {
        render "Bad"
    }
}

you want to verify the logic that is executed on a good form submission and the logic that is executed on a duplicate submission. Testing the bad submission is simple. Just invoke the controller:

ここでフォームの送信が成功する場合と、2重送信となる場合のロジックを検証したいとします。2重送信となる場合のテストは、単にコントローラをすることで簡単に実行できます。

void testDuplicateFormSubmission() {
    controller.handleForm()
    assert "Bad" == response.text
}

Testing the successful submission requires providing an appropriate SynchronizerToken:

フォームの送信が成功する場合のテストは適切なSynchronizerTokenが必要となります。

import org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerToken
...

void testValidFormSubmission() { def tokenHolder = SynchronizerTokensHolder.store(session)

params[SynchronizerTokensHolder.TOKEN_URI] = '/controller/handleForm' params[SynchronizerTokensHolder.TOKEN_KEY] = tokenHolder.generateToken(params[SynchronizerTokensHolder.TOKEN_URI])

controller.handleForm() assert "Good" == response.text }

If you test both the valid and the invalid request in the same test be sure to reset the response between executions of the controller:

もし、有効/無効のリクエストを両方ともテストしたい場合、コントローラのメソッド実行の間で、レスポンスをリセットしてください。

controller.handleForm() // first execution
…
response.reset()
…
controller.handleForm() // second execution

Testing File Upload

ファイルアップロードのテスト

You use the GrailsMockMultipartFile class to test file uploads. For example consider the following controller action:

ファイルアップロードをテストするためには、GrailsMockMultipartFileクラスを使います。例えば、次のコントローラアクションを見てください。

def uploadFile() {
    MultipartFile file = request.getFile("myFile")
    file.transferTo(new File("/local/disk/myFile"))
}

To test this action you can register a GrailsMockMultipartFile with the request:

このアクションをテストするには、リクエストにGrailsMockMultipartFileを設定してください。

void testFileUpload() {
    final file = new GrailsMockMultipartFile("myFile", "foo".bytes)
    request.addFile(file)
    controller.uploadFile()

assert file.targetFileLocation.path == "/local/disk/myFile" }

The GrailsMockMultipartFile constructor arguments are the name and contents of the file. It has a mock implementation of the transferTo method that simply records the targetFileLocation and doesn't write to disk.

GrailsMockMultipartFileのコンストラクタの引数はファイル名とファイルの内容です。これはtransferToのモック実装をもっており、ファイルには書き込まずにtargetFileLocationとして値を保持します。

Testing Command Objects

Commnadオブジェクトのテスト

Special support exists for testing command object handling with the mockCommandObject method. For example consider the following action:

mockCommandObjectメソッドにはCommandオブジェクトの処理をテストするための特別な機能があります。例えば、次のアクションを見てください。

def handleCommand(SimpleCommand simple) {
    if (simple.hasErrors()) {
        render "Bad"
    }
    else {
        render "Good"
    }
}

To test this you mock the command object, populate it and then validate it as follows:

これをテストするために、次のようにCommandオブジェクトをモック化した上で、データを投入して検証してください。

void testInvalidCommand() {
    def cmd = mockCommandObject(SimpleCommand)
    cmd.name = '' // doesn't allow blank names

cmd.validate() controller.handleCommand(cmd)

assert response.text == 'Bad' }

Testing Calling Tag Libraries

タグライブラリの呼び出しテスト

You can test calling tag libraries using ControllerUnitTestMixin, although the mechanism for testing the tag called varies from tag to tag. For example to test a call to the message tag, add a message to the messageSource. Consider the following action:

タグごとに必要となるテストの方法は異なりますが、タグライブラリの呼びしはControllerUnitTestMixinを使用することでテストできます。例えば、messageタグを呼び出すテストでは、messageSourceにメッセージを加えます。次のアクションを見てください。

def showMessage() {
    render g.message(code: "foo.bar")
}

This can be tested as follows:

これは次のようにテストをします。

void testRenderBasicTemplateWithTags() {
    messageSource.addMessage("foo.bar", request.locale, "Hello World")

controller.showMessage()

assert response.text == "Hello World" }

12.1.2 タグライブラリのユニットテスト

The Basics

基本

Tag libraries and GSP pages can be tested with the grails.test.mixin.web.GroovyPageUnitTestMixin mixin. To use the mixin declare which tag library is under test with the TestFor annotation:

タグライブラリとGSPは、grails.test.mixin.web.GroovyPageUnitTestMixinのMixinでテストできます。Mixinを使用するために、タグライブラリをTestForアノテーションの中に宣言します。

@TestFor(SimpleTagLib)
class SimpleTagLibTests {

}

Note that if you are testing invocation of a custom tag from a controller you can combine the ControllerUnitTestMixin and the GroovyPageUnitTestMixin using the Mock annotation:

もし、コントローラからカスタムタグの呼び出しをテストする場合、Mockアノテーションを使用してControllerUnitTestMixinGroovyPageUnitTestMixinを組み合わせることができます。

@TestFor(SimpleController)
@Mock(SimpleTagLib)
class GroovyPageUnitTestMixinTests {

}

Testing Custom Tags

カスタムタグのテスト

The core Grails tags don't need to be enabled during testing, however custom tag libraries do. The GroovyPageUnitTestMixin class provides a mockTagLib() method that you can use to mock a custom tag library. For example consider the following tag library:

Grailsコアのタグはテスト中に有効にする必要はありませんが、カスタムタグライブラリは有効にする必要があります。GroovyPageUnitTestMixinクラスは、カスタムタグライブラリをモック化するために使えるmockTagLib()メソッドを提供しています。

class SimpleTagLib {

static namespace = 's'

def hello = { attrs, body -> out << "Hello ${attrs.name ?: 'World'}" }

def bye = { attrs, body -> out << "Bye ${attrs.author.name ?: 'World'}" } }

You can test this tag library by using TestFor and supplying the name of the tag library:

TestForを使用し、タグライブラリの名前を記載することによって、上記のタグライブラリをテストできます。

@TestFor(SimpleTagLib)
class SimpleTagLibTests {
    void testHelloTag() {
        assert applyTemplate('<s:hello />') == 'Hello World'
        assert applyTemplate('<s:hello name="Fred" />') == 'Hello Fred'
        assert applyTemplate('<s:bye author="${author}" />', [author: new Author(name: 'Fred')]) == 'Bye Fred'
    }
}

Alternatively, you can use the TestMixin annotation and mock multiple tag libraries using the mockTagLib() method:

代わりに、TestMixinアノテーションとmockTagLib()メソッドにより、複数のタグライブラリをモック化することができます。

@grails.test.mixin.TestMixin(GroovyPageUnitTestMixin)
class MultipleTagLibraryTests {

@Test void testMuliple() { mockTagLib(FirstTagLib) mockTagLib(SecondTagLib)

… } }

The GroovyPageUnitTestMixin provides convenience methods for asserting that the template output equals or matches an expected value.

GroovyPageUnitTestMixinはテンプレート出力が期待した値と同じであることを検証するために便利なメソッドを提供しています。

@grails.test.mixin.TestMixin(GroovyPageUnitTestMixin)
class MultipleTagLibraryTests {

@Test void testMuliple() { mockTagLib(FirstTagLib) mockTagLib(SecondTagLib) assertOutputEquals ('Hello World', '<s:hello />') assertOutputMatches (/.*Fred.*/, '<s:hello name="Fred" />') } }

Testing View and Template Rendering

表示とテンプレートのレンダリングテスト

You can test rendering of views and templates in grails-app/views via the render(Map) method provided by GroovyPageUnitTestMixin :

GroovyPageUnitTestMixinで提供されているrender(Map)メソッドを使ってgrails-app/views内にあるビューとテンプレートのレンダリングをテストできます。

def result = render(template: "/simple/hello")
assert result == "Hello World"

This will attempt to render a template found at the location grails-app/views/simple/_hello.gsp. Note that if the template depends on any custom tag libraries you need to call mockTagLib as described in the previous section.

これは、grails-app/views/simple/_hello.gspに配置されているテンプレートをレンダリングします。もしテンプレートがいくつかのカスタムタグライブラリに依存している場合、前の節で記載したmockTagLibを呼び出す必要があります。

12.1.3 ドメインのユニットテスト

Overview

概要

The mocking support described here is best used when testing non-domain artifacts that use domain classes, to let you focus on testing the artifact without needing a database. But when testing persistence it's best to use integration tests which configure Hibernate and use a database.

モック機能のサポートは、非ドメインクラスがドメインクラスを使用している場合に、データベースを必要とせず、テストに集中できるという意味では最適な方法です。しかし、ドメインの永続化のテストを行いたい場合はHibernateとデータベースを使用するIntegrationテストが最適な方法です。

Domain class interaction can be tested without involving a database connection using DomainClassUnitTestMixin. This implementation mimics the behavior of GORM against an in-memory ConcurrentHashMap implementation. Note that this has limitations compared to a real GORM implementation. The following features of GORM for Hibernate can only be tested within an integration test:

ドメインクラスとしての振る舞いはDomainClassUnitTestMixinを使用することで、データベースを必要とせずにテストを行うことができます。この実装はGORMの振る舞いを擬似した、メモリ上のConcurrentHashMapです。この実装は実際のGORMの動作と比べて制限があることに注意してください。以下のHibernateに対するGORMの機能はIntegrationテストでのみテストできます。

  • String-based HQL queries
  • composite identifiers
  • dirty checking methods
  • any direct interaction with Hibernate

  • 文字列ベースのHQLクエリ
  • 複合主キー
  • dirtyチェックメソッド
  • Hibernateの直接操作

However a large, commonly-used portion of the GORM API can be mocked using DomainClassUnitTestMixin including:

上記以外の、よく使用されるGORM APIの大部分はDomainClassUnitTestMixinを使用することでモック化することができます。

  • Simple persistence methods like save(), delete() etc.
  • Dynamic Finders
  • Named Queries
  • Query-by-example
  • GORM Events

  • save()delete()といった永続化メソッド
  • ダイナミックファインダー
  • 名前付きクエリ
  • Exampleによるクエリ
  • GORMのイベント

If something isn't supported then GrailsUnitTestMixin's mockFor method can come in handy to mock the missing pieces. Alternatively you can write an integration test which bootstraps the complete Grails environment at a cost of test execution time.

もしサポートされてない部分があった場合でも、GrailsUnitTestMixinmockForメソッドを使用することで足りない部分をモック化することができます。または、テストの実行時間はかかりますが、完全にGrails環境が立ち上がるIntegrationテストを使用することもできます。

The Basics

基本

DomainClassUnitTestMixin is typically used in combination with testing either a controller, service or tag library where the domain is a mock collaborator defined by the Mock annotation:

DomainClassUnitTestMixinは、通常コントローラやサービス、またはタグライブラリといった、Mockアノテーションでドメインがモックとして協調動作する必要がある場所で使用されます。

import grails.test.mixin.*

@TestFor(SimpleController) @Mock(Simple) class SimpleControllerTests {

}

The example above tests the SimpleController class and mocks the behavior of the Simple domain class as well. For example consider a typical scaffolded save controller action:

上記の例ではSimpleControllerのテストでSimpleドメインクラスとして振る舞うモックを宣言しています。例えば典型的なスキャフォルドで生成されたコントローラのsaveアクションについて考えてみます。

class BookController {
    def save() {
        def book = new Book(params)
        if (book.save(flush: true)) {
            flash.message = message(
                    code: 'default.created.message',
                    args: [message(code: 'book.label',
                                   default: 'Book'), book.id])}"
            redirect(action: "show", id: book.id)
        }
        else {
            render(view: "create", model: [bookInstance: book])
        }
    }
}

Tests for this action can be written as follows:

このアクションに対するテストは次のように書けます。

import grails.test.mixin.*

@TestFor(BookController) @Mock(Book) class BookControllerTests {

void testSaveInvalidBook() { controller.save()

assert model.bookInstance != null assert view == '/book/create' }

void testSaveValidBook() { params.title = "The Stand" params.pages = "500"

controller.save()

assert response.redirectedUrl == '/book/show/1' assert flash.message != null assert Book.count() == 1 } }

Mock annotation also supports a list of mock collaborators if you have more than one domain to mock:

複数のドメインのモックが必要な場合はMockアノテーションにリストで指定することができます。

@TestFor(BookController)
@Mock([Book, Author])
class BookControllerTests {
   …
}

Alternatively you can also use the DomainClassUnitTestMixin directly with the TestMixin annotation:

別の方法としてTestMixinアノテーションに直接DomainClassUnitTestMixinを指定する方法もあります。

import grails.test.mixin.domain.DomainClassUnitTestMixin

@TestFor(BookController) @TestMixin(DomainClassUnitTestMixin) class BookControllerTests { … }

And then call the mockDomain method to mock domains during your test:

そしてテストの中でドメインをモック化するmockDomainメソッドを呼び出します。

void testSave() {
    mockDomain(Author)
    mockDomain(Book)
}

The mockDomain method also includes an additional parameter that lets you pass a Map of Maps to configure a domain, which is useful for fixture-like data:

mockDomainメソッドは、ドメインを構築するマップの一覧を与えることで、データのフィクスチャを生成するような使い方もできます。

void testSave() {
    mockDomain(Book, [
            [title: "The Stand", pages: 1000],
            [title: "The Shining", pages: 400],
            [title: "Along Came a Spider", pages: 300] ])
}

Testing Constraints

制約のテスト

There are 4 types of validateable classes:

  1. Domain Classes
  2. Classes Marked With The @Validateable Annotation
  3. Command Objects Which Have Been Made Valdiateable Automatically
  4. Classes Configured To Be Validateable via The grails.validateable.classes Config.groovy Property

The first 3 are easily testable in a unit test with no special configuration necessary as long as the test method is marked with @TestFor or explicitly applies the GrailsUnitTestMixin using @TestMixin. See the examples below.

// src/groovy/com/demo/MyValidateable.groovy
package com.demo

@grails.validation.Validateable class MyValidateable { String name Integer age

static constraints = { name matches: /[A-Z].*/ age range: 1..99 } }

// grails-app/domain/com/demo/Person.groovy
package com.demo

class Person { String name

static constraints = { name matches: /[A-Z].*/ } }

// grails-app/controllers/com/demo/DemoController.groovy
package com.demo

class DemoController {

def addItems(MyCommandObject co) { if(co.hasErrors()) { render 'something went wrong' } else { render 'items have been added' } } }

class MyCommandObject { Integer numberOfItems

static constraints = { numberOfItems range: 1..10 } }

// test/unit/com/demo/PersonSpec.groovy
package com.demo

import grails.test.mixin.TestFor import spock.lang.Specification

@TestFor(Person) class PersonSpec extends Specification {

void "Test that name must begin with an upper case letter"() { when: 'the name begins with a lower letter' def p = new Person(name: 'jeff')

then: 'validation should fail' !p.validate()

when: 'the name begins with an upper case letter' p = new Person(name: 'Jeff')

then: 'validation should pass' p.validate() } }

// test/unit/com/demo/DemoControllerSpec.groovy
package com.demo

import grails.test.mixin.TestFor import spock.lang.Specification

@TestFor(DemoController) class DemoControllerSpec extends Specification {

void 'Test an invalid number of items'() { when: params.numberOfItems = 42 controller.addItems()

then: response.text == 'something went wrong' }

void 'Test a valid number of items'() { when: params.numberOfItems = 8 controller.addItems()

then: response.text == 'items have been added' } }

// test/unit/com/demo/MyValidateableSpec.groovy
package com.demo

import grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin import spock.lang.Specification

@TestMixin(GrailsUnitTestMixin) class MyValidateableSpec extends Specification {

void 'Test validate can be invoked in a unit test with no special configuration'() { when: 'an object is valid' def validateable = new MyValidateable(name: 'Kirk', age: 47)

then: 'validate() returns true and there are no errors' validateable.validate() !validateable.hasErrors() validateable.errors.errorCount == 0

when: 'an object is invalid' validateable.name = 'kirk'

then: 'validate() returns false and the appropriate error is created' !validateable.validate() validateable.hasErrors() validateable.errors.errorCount == 1 validateable.errors['name'].code == 'matches.invalid'

when: 'the clearErrors() is called' validateable.clearErrors()

then: 'the errors are gone' !validateable.hasErrors() validateable.errors.errorCount == 0

when: 'the object is put back in a valid state' validateable.name = 'Kirk'

then: 'validate() returns true and there are no errors' validateable.validate() !validateable.hasErrors() validateable.errors.errorCount == 0 } }

// test/unit/com/demo/MyCommandObjectSpec.groovy
package com.demo

import grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin import spock.lang.Specification

@TestMixin(GrailsUnitTestMixin) class MyCommandObjectSpec extends Specification {

void 'Test that numberOfItems must be between 1 and 10'() { when: 'numberOfItems is less than 1' def co = new MyCommandObject() co.numberOfItems = 0

then: 'validation fails' !co.validate() co.hasErrors() co.errors['numberOfItems'].code == 'range.toosmall'

when: 'numberOfItems is greater than 10' co.numberOfItems = 11

then: 'validation fails' !co.validate() co.hasErrors() co.errors['numberOfItems'].code == 'range.toobig'

when: 'numberOfItems is greater than 1' co.numberOfItems = 1

then: 'validation succeeds' co.validate() !co.hasErrors()

when: 'numberOfItems is greater than 10' co.numberOfItems = 10

then: 'validation succeeds' co.validate() !co.hasErrors() } }

For validateable classes which are not one of the first 3 types listed above but are configured with the grails.validateable.classes property in Config.groovy, one additional step is required to test validation. GrailsUnitTestMixin provides a method named mockForConstraintsTests that will mock validation support for these classes. See the example below.

// src/groovy/com/demo/Book.groovy
package com.demo

class Book { String title String author

static constraints = { author minSize: 5 } }

// grails-app/conf/Config.groovy
grails.validateable.classes = [com.demo.Book]

// ...

// test/unit/com/demo/BookSpec.groovy
package com.demo

import grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin import spock.lang.Specification

@TestMixin(GrailsUnitTestMixin) class BookSpec extends Specification {

void 'Test validation'() { given: mockForConstraintsTests Book

when: 'the author name has only 4 characters' def book = new Book() book.author = 'Jeff'

then: 'validation should fail' !book.validate() book.hasErrors() book.errors['author'] == 'minSize'

when: 'the author name has 5 characters' book.author = 'Jacob'

then: 'validation should pass' book.validate() !book.hasErrors() } }

Note that the mockForConstraintsTests method changes the behavior of the errors object such that something like book.errors'author' will evaluate to the name of the failed constraint, not a org.springframework.validation.FieldError object. This is convenient for unit tests. If your unit test really does want a reference to the org.springframework.validation.FieldError object use something like book.errors.getFieldError('author').

That's it for testing constraints. One final thing we would like to say is that testing the constraints in this way catches a common error: typos in the "constraints" property name which is a mistake that is easy to make and equally easy to overlook. A unit test for your constraints will highlight the problem straight away.

12.1.4 フィルタのユニットテスト

Unit testing filters is typically a matter of testing a controller where a filter is a mock collaborator. For example consider the following filters class:
フィルタをユニットテストするには、一般的に、フィルタがモックコラボレータであるようなコントローラをテストすることになります。 例えば、次のフィルタクラスを考えてみましょう:

class CancellingFilters {
    def filters = {
        all(controller:"simple", action:"list") {
            before = {
                redirect(controller:"book")
                return false
            }
        }
    }
}

This filter interceptors the list action of the simple controller and redirects to the book controller. To test this filter you start off with a test that targets the SimpleController class and add the CancellingFilters as a mock collaborator:
このフィルタはsimpleコントローラのlistアクションをインターセプトし、bookコントローラにリダイレクトします。このフィルタをテストするには、まずSimpleControllerクラスを対象としたテストを作り、CancellingFiltersをモックコラボレータとして設定します:

@TestFor(SimpleController)
@Mock(CancellingFilters)
class SimpleControllerTests {

}

You can then implement a test that uses the withFilters method to wrap the call to an action in filter execution:
次に、フィルタを通して実行されるアクションの呼び出しをwithFiltersメソッドで囲むようにテストを実装します:

void testInvocationOfListActionIsFiltered() {
    withFilters(action:"list") {
        controller.list()
    }
    assert response.redirectedUrl == '/book'
}

Note that the action parameter is required because it is unknown what the action to invoke is until the action is actually called. The controller parameter is optional and taken from the controller under test. If it is another controller you are testing then you can specify it:
実際にアクションが呼び出されるまで、どのアクションが実行されるか不明なため、actionパラメータが必須であることに注意してください。 controllerパラメータは省略可能です。省略時はテスト対象のコントローラが適用されます。 もしテストしているのが別のコントローラである場合はそれを指定します。

withFilters(controller:"book",action:"list") {
    controller.list()
}

12.1.5 URLマッピングのユニットテスト

The Basics

基本

Testing URL mappings can be done with the TestFor annotation testing a particular URL mappings class. For example to test the default URL mappings you can do the following:

URLマッピングをテストするには、TestForアノテーションを使用します。例えば、デフォルトのURLマッピングをテストするためには次のように使用します。

import org.example.AuthorController
import org.example.SimpleController

@TestFor(UrlMappings) @Mock([AuthorController, SimpleController]) class UrlMappingsTests { … }

As you can see, any controller that is the target of a URL mapping that you're testing must be added to the @Mock annotation.

上記のように、テストを実施するURLマッピングの対象となるコントローラにはMockアノテーションを追加しなければなりません。

Note that since the default UrlMappings class is in the default package your test must also be in the default package

UrlMappingsクラスがデフォルトパッケージの中にあるので、あなたが実行するテストもデフォルトパッケージの中になければいけません。

With that done there are a number of useful methods that are defined by the grails.test.mixin.web.UrlMappingsUnitTestMixin for testing URL mappings. These include:

URLマッピングをテストするためにgrails.test.mixin.web.UrlMappingsUnitTestMixinには以下のような便利なメソッドが定義されています。

  • assertForwardUrlMapping - Asserts a URL mapping is forwarded for the given controller class (note that controller will need to be defined as a mock collaborate for this to work)

  • assertForwardUrlMapping - 指定したコントローラクラスにフォワードするURLマッピングを検証する(コントローラはモックコラボレータとして定義される必要があることに注意してください)

  • assertReverseUrlMapping - Asserts that the given URL is produced when reverse mapping a link to a given controller and action

  • assertReverseUrlMapping - 指定したURLが、与えられたコントローラとアクションからリバースマッピングしたリンクとして生成されるか検証する

  • assertUrlMapping - Asserts a URL mapping is valid for the given URL. This combines the assertForwardUrlMapping and assertReverseUrlMapping assertions

  • assertUrlMapping - 指定したURLに対応するURLマッピングの妥当性を検証する。これは、assertForwardUrlMappingassertReverseUrlMappingを組み合わせたものです。

Asserting Forward URL Mappings

URLマッピングの転送の検証

You use assertForwardUrlMapping to assert that a given URL maps to a given controller. For example, consider the following URL mappings:

指定したURLが、期待したコントローラにマップされるか検証するためにassertForwardUrlMappingが使用できます。例えば、以下のようなURLマッピングについて考えてみます。

static mappings = {
    "/action1"(controller: "simple", action: "action1")
    "/action2"(controller: "simple", action: "action2")
}

The following test can be written to assert these URL mappings:

このようなURLマッピングのテストは次のように書けます。

void testUrlMappings() {

assertForwardUrlMapping("/action1", controller: 'simple', action: "action1")

assertForwardUrlMapping("/action2", controller: 'simple', action: "action2")

shouldFail { assertForwardUrlMapping("/action2", controller: 'simple', action: "action1") } }

Assert Reverse URL Mappings

URLマッピングのリバース検証

You use assertReverseUrlMapping to check that correct links are produced for your URL mapping when using the link tag in GSP views. An example test is largely identical to the previous listing except you use assertReverseUrlMapping instead of assertForwardUrlMapping. Note that you can combine these 2 assertions with assertUrlMapping.

GSPのビューでlinkタグを使用した場合に、URLマッピングから生成されるリンクを確認(チェック)するためにassertReverseUrlMappingを使用できます。 assertReverseUrlMappingの代わりにassertForwardUrlMappingを使用する以外は上記の例とほとんど同じです。 assertUrlMappingはこれら2つのアサーションを組み合わせた検証が出来ます。

Simulating Controller Mapping

コントローラのマッピングをシミュレート

In addition to the assertions to check the validity of URL mappings you can also simulate mapping to a controller by using your UrlMappings as a mock collaborator and the mapURI method. For example:

URLマッピングの妥当性をチェックするためのアサーションに加えて、UrlMappingsをモックとして指定しmapURIメソッドを使用することで、コントローラへのマッピングをシミュレートすることができます。

@TestFor(SimpleController)
@Mock(UrlMappings)
class SimpleControllerTests {

void testControllerMapping() {

SimpleController controller = mapURI('/simple/list') assert controller != null

def model = controller.list() assert model != null } }

12.1.6 コラボレータのモック化

Beyond the specific targeted mocking APIs there is also an all-purpose mockFor() method that is available when using the TestFor annotation. The signature of mockFor is:
ドメインをモックするなど特定の目的をもったモックAPIの他に、汎用的に使えるmockFor()メソッドがあります。これはTestForアノテーションを使用している場合にも使用できます。mockForは以下のように使用します。

mockFor(class, loose = false)

This is general-purpose mocking that lets you set up either strict or loose demands on a class.
mockForを使用したモックでは、demand(要求)がstrict(厳密)、またはloose(緩やか)のどちらであるかを指定する必要があります。

This method is surprisingly intuitive to use. By default it will create a strict mock control object (one for which the order in which methods are called is important) that you can use to specify demands:
デフォルトではstrictなモック制御オブジェクト(メソッドの呼び出し順序をチェックする)として生成し、demandを次のように指定します。

def strictControl = mockFor(MyService)
strictControl.demand.someMethod(0..2) { String arg1, int arg2 -> … }
strictControl.demand.static.aStaticMethod {-> … }

Notice that you can mock static as well as instance methods by using the "static" property. You then specify the name of the method to mock, with an optional range argument. This range determines how many times you expect the method to be called, and if the number of invocations falls outside of that range (either too few or too many) then an assertion error will be thrown. If no range is specified, a default of "1..1" is assumed, i.e. that the method must be called exactly once.
"static"プロパティを使用することで、インスタンスメソッド同様にstaticなメソッドをモックすることができます。また、モックするメソッドには、必要に応じてrange(範囲)を引数に指定できます。このrangeは期待するメソッドの呼び出し回数を表しており、もし呼び出し回数がこの範囲を外れた場合(多すぎたり、少なすぎたりした場合)は、アサーションエラーがスローされます。rangeを指定しなかった場合は、デフォルトで"1..1"が指定され、メソッドが1度だけ呼び出されること意味しています。

The last part of a demand is a closure representing the implementation of the mock method. The closure arguments must match the number and types of the mocked method, but otherwise you are free to add whatever you want in the body.
demandの最後の引数は、モックの実装を表すクロージャです。クロージャの引数は、モックするメソッドの引数の数と型が一致している必要がありますが、それ以外は自由に中身を実装できます。

Call mockControl.createMock() to get an actual mock instance of the class that you are mocking. You can call this multiple times to create as many mock instances as you need. And once you have executed the test method, call mockControl.verify() to check that the expected methods were called.
モッククラスの定義が完了した後に、mockControl.createMock()メソッドを呼ぶことで、モックインスタンスを作成します。複数のモックインスタンスが必要な場合は、必要なだけこのメソッドを呼び出すことで、複数のモックインスタンスが作成できます。また期待するメソッドの呼び出しを検証するにはmockControl.verify()を呼び出してください。

Grails mocks also provide a demandExplicit method that can be used in place of demand. This will check the mocked class's metaClass and throw an ExplicitDemandException if a method with that name and signature doesn't exist. For example, given the service:
Grailsのモックは、demandの代わりにdemandExplicitメソッドも提供しています。これはモックするクラスのmetaClassをチェックし、もしそのメソッドの名前、シグネチャが存在しない場合に、ExplicitDemandExceptionをスローします。例えば次のようなサービスがあるとします。

class MyService {
    def someMethod(String s) { … }
}

The following mocking works the same as demand
demandと同じようにモックできます。

def strictControl = mockFor(MyService)
//Works just like the demand method since method signature exists on the class
strictControl.demandExplicit.someMethod(1) { String arg1  }

While this mocking throws an ExplicitDemandException when the test is run.
以下はメソッドのシグネイチャが存在しないため、テストを実行した際にExplicitDemandExceptionをスローします。
def strictControl = mockFor(MyService)
//Throws ExplicitDemandException because method signature doesn't exist
strictControl.demandExplicit.someMethod(1) { String arg1, String arg2  }

Using demandExplicit should be the preferred method for mocking as it is more likely to catch issues when changing method signatures. Use demand when the method to be mocked is added dynamically, otherwise use demandExplicit.
demandExplicitを使用することで、メソッドのシグネチャを変更した際に、問題を検出しやすくなります。このため、動的に追加されるメソッドに対してはdemandを使用し、そうでなければdemandExplicitを使用してください。

Lastly, the call:
最後に以下のコードを見てください。

def looseControl = mockFor(MyService, true)

will create a mock control object that has only loose expectations, i.e. the order that methods are invoked does not matter.
これはlooseなモック制御オブジェクトを作成します。別の言い方をすると、これにより呼び出し順序をチェックしなくなります。

12.1.7 コーデックのモック化

The GrailsUnitTestMixin provides a mockCodec method for mocking custom codecs which may be invoked while a unit test is running.

GrailsUnitTestMixinカスタムコーデックのモックを生成するためのmockCodecメソッドを提供しています。このメソッドはユニットテストの実施中に呼び出される可能性があります。

mockCodec(MyCustomCodec)

Failing to mock a codec which is invoked while a unit test is running may result in a MissingMethodException.

コーデックのモック生成に失敗している場合は、ユニットテストがMissingMethodExceptionで終了する可能性があります。

12.2 インテグレーションテスト

Integration tests differ from unit tests in that you have full access to the Grails environment within the test. Grails uses an in-memory H2 database for integration tests and clears out all the data from the database between tests.
インテグレーションテストはGrails実行環境にフルアクセス可能なところが、ユニットテストとは異なっています。GrailsはインテグレーションテストのためにインメモリのH2データベースを使用するので、テスト毎にデータベースの全てのデータは消去されます。

One thing to bear in mind is that logging is enabled for your application classes, but it is different from logging in tests. So if you have something like this:
一つ心にとめておいて欲しいことは、テスト対象のアプリケーションクラスのロギングを有効にしたとしても、アプリケーション内で有効なロギングは、テスト内で有効なロギングとは異なります。もし、テスト中にログを取りたいならば以下のように記述します:

class MyServiceTests extends GroovyTestCase {
    void testSomething() {
        log.info "Starting tests"
        …
    }
}

the "starting tests" message is logged using a different system than the one used by the application. The log property in the example above is an instance of java.util.logging.Logger (inherited from the base class, not injected by Grails), which doesn't have the same methods as the log property injected into your application artifacts. For example, it doesn't have debug() or trace() methods, and the equivalent of warn() is in fact warning().
"starting tests"のメッセージはアプリケーションが使っているのとは異なるロガーによりログが記録されます。上の例におけるlogのプロパティにはjava.util.logging.Loggerのインスタンスが設定され(Grailsによって注入されるのではなく、ベースクラスから継承される)、アプリケーション側で注入されるlogプロパティと同じメソッドは持っていません。例えば、debug()trace()メソッドがなく、warn()(と同じ意味を持つもの)がwarning()になります。

h4. Transactions

トランザクション

Integration tests run inside a database transaction by default, which is rolled back at the end of the each test. This means that data saved during a test is not persisted to the database. Add a transactional property to your test class to check transactional behaviour:
インテグレーションテストはデフォルトでデータベーストランザクションの中で実行され、テスト毎にテストの最後でロールバックされます。つまり、テスト中に保存したデータはデータベースには永続化されないことを意味します。また、transactionalプロパティをテストクラスに追加することで、トランザクション制御を抑止することができます:

class MyServiceTests extends GroovyTestCase {
    static transactional = false

void testMyTransactionalServiceMethod() { … } }

Be sure to remove any persisted data from a non-transactional test, for example in the tearDown method, so these tests don't interfere with standard transactional tests that expect a clean database.
トランザクション管理されていないテストでは、クリーンなデータベースを期待している通常のテストに影響を与えないよう、tearDownメソッドなどで、永続化されたすべてのデータを削除するようにしてください。

h4. Testing Controllers

コントローラのテスト

To test controllers you first have to understand the Spring Mock Library.
コントローラをテストするためには、まずSpringモックライブラリを理解する必要があります。

Grails automatically configures each test with a MockHttpServletRequest, MockHttpServletResponse, and MockHttpSession that you can use in your tests. For example consider the following controller:
GrailsはMockHttpServletRequestMockHttpServletResponseMockHttpSessionをテストで使えるように自動的に設定します。例えば、以下のコントローラを考えてみましょう:

class FooController {

def text() { render "bar" }

def someRedirect() { redirect(action:"bar") } }

The tests for this would be:
このテストは次のようになるでしょう:

class FooControllerTests extends GroovyTestCase {

void testText() { def fc = new FooController() fc.text() assertEquals "bar", fc.response.contentAsString }

void testSomeRedirect() { def fc = new FooController() fc.someRedirect() assertEquals "/foo/bar", fc.response.redirectedUrl } }

In the above case response is an instance of MockHttpServletResponse which we can use to obtain the generated content with contentAsString (when writing to the response) or the redirected URL. These mocked versions of the Servlet API are completely mutable (unlike the real versions) and hence you can set properties on the request such as the contextPath and so on.
上記のresponseMockHttpServletResponseのインスタンスです。このインスタンスでは、レスポンスを書き出すときであればcontentAsStringにより生成されたコンテンツが取得でき、リダイレクトの場合はリダイレクトされたURLが取得できます。これらのServlet APIのモックバージョンは(実際のAPIとは異なり)何でも変更可能で、contextPathなどリクエストのプロパティについても設定可能です。

Grails does not invoke interceptors or servlet filters when calling actions during integration testing. You should test interceptors and filters in isolation, using functional testing if necessary.
Grailsはインテグレーションテスト実行中にアクションを呼ぶ際、決してインターセプターやサーブレットフィルターを実行しません。もしテストが必要なら、ファンクショナルテストを使ってインターセプターやフィルターを個別にテストする必要があります。

h4. Testing Controllers with Services

サービスを伴うコントローラのテスト

If your controller references a service (or other Spring beans), you have to explicitly initialise the service from your test.
もしコントローラがサービス(もしくは他のSpringビーン)を参照しているなら、テストにおいて明示的にサービスを初期化する必要があります。

Given a controller using a service:
サービスを使うコントローラがあるとします:

class FilmStarsController {
    def popularityService

def update() { // do something with popularityService } }

The test for this would be:
このテストは次のようになるでしょう:

class FilmStarsTests extends GroovyTestCase {
    def popularityService

void testInjectedServiceInController () { def fsc = new FilmStarsController() fsc.popularityService = popularityService fsc.update() } }

h4. Testing Controller Command Objects

コマンドオブジェクトを使っているコントローラのテスト

With command objects you just supply parameters to the request and it will automatically do the command object work for you when you call your action with no parameters:
コマンドオブジェクトを使っていて引数を指定せずアクションを呼び出す場合でも、リクエストにただパラメータを設定するだけで、自動的にコマンドオブジェクトは動作し設定されます:

Given a controller using a command object:
コマンドオブジェクトを使っているコントローラがあるとします:

class AuthenticationController {
    def signup(SignupForm form) {
        …
    }
}

You can then test it like this:
この場合このようにテストできます:

def controller = new AuthenticationController()
controller.params.login = "marcpalmer"
controller.params.password = "secret"
controller.params.passwordConfirm = "secret"
controller.signup()

Grails auto-magically sees your call to signup() as a call to the action and populates the command object from the mocked request parameters. During controller testing, the params are mutable with a mocked request supplied by Grails.
Grailsはアクション呼び出しのsignup()を呼び出しているのを見て、モック化されたリクエストパラメータからなんと自動的にコマンドオブジェクトに値を渡してくれます。ちなみに、コントローラのテストにおいて、Grailsが用意したモック化されたリクエストのparamsは変更可能です。

h4. Testing Controllers and the render Method

コントローラとレンダーメソッドのテスト

The render method lets you render a custom view at any point within the body of an action. For instance, consider the example below:
renderメソッドはアクション定義のあらゆる場所においてカスタムビューをレンダリングできます。例えば、下記の例を考えてみましょう:

def save() {
    def book = Book(params)
    if (book.save()) {
        // handle
    }
    else {
        render(view:"create", model:[book:book])
    }
}

In the above example the result of the model of the action is not available as the return value, but instead is stored within the modelAndView property of the controller. The modelAndView property is an instance of Spring MVC's ModelAndView class and you can use it to the test the result of an action:
上記の例ではアクションにおけるモデルの結果は戻り値としては得られませんが、コントローラのmodelAndViewプロパティの中には保存されています。modelAndViewプロパティはSpring MVCのModelAndViewクラスで、アクションの結果をテストするのに利用できます:

def bookController = new BookController()
bookController.save()
def model = bookController.modelAndView.model.book

h4. Simulating Request Data

リクエストデータをシミュレートする

You can use the Spring MockHttpServletRequest to test an action that requires request data, for example a REST web service. For example consider this action which performs data binding from an incoming request:
例えば、REST Webサービスのようなリクエストデータが必要なアクションをテストする場合、Spring MockHttpServletRequestを使うことができます。例として、入力されたリクエストからデータバインディングを実行するこのアクションを考えてみましょう:

def create() {
    [book: new Book(params.book)]
}

To simulate the 'book' parameter as an XML request you could do something like the following:
XMLリクエストとしての'book'引数をシミュレートするには、次のように実行できるでしょう:

void testCreateWithXML() {

def controller = new BookController()

controller.request.contentType = 'text/xml' controller.request.content = '''\ <?xml version="1.0" encoding="ISO-8859-1"?> <book> <title>The Stand</title> … </book> '''.stripIndent().getBytes() // note we need the bytes

def model = controller.create() assert model.book assertEquals "The Stand", model.book.title }

The same can be achieved with a JSON request:
JSONリクエストについても同じように実現できます:

void testCreateWithJSON() {

def controller = new BookController()

controller.request.contentType = "application/json" controller.request.content = '{"id":1,"class":"Book","title":"The Stand"}'.getBytes()

def model = controller.create() assert model.book assertEquals "The Stand", model.book.title }

With JSON don't forget the class property to specify the name the target type to bind to. In XML this is implicit within the name of the <book> node, but this property is required as part of the JSON packet.
JSONを用いる場合、classプロパティにて結びつけるターゲットの型の名前を指定することを忘れてはいけません。XMLでは暗黙的に<book>ノードの名前が使われますが、JSONではこのプロパティがJSONパケットの一部として必要になります。

For more information on the subject of REST web services see the section on REST.
RESTウェブサービスについてのさらなる情報については、RESTのセクションを参照してください。

h4. Testing Web Flows

Webフローのテスト

Testing Web Flows requires a special test harness called grails.test.WebFlowTestCase which subclasses Spring Web Flow's AbstractFlowExecutionTests class.
Webフローのテストは Spring Web Flowの AbstractFlowExecutionTestsクラスのサブクラスであるgrails.test.WebFlowTestCaseと呼ばれる特別なテストハーネスが必要になります。

Subclasses of WebFlowTestCase must be integration tests
WebFlowTestCaseのサブクラスは、必ずインテグレーションテストでなければなりません。

For example given this simple flow:
例えばこのようなシンプルなフローがあるとします:

class ExampleController {

def exampleFlow() { start { on("go") { flow.hello = "world" }.to "next" } next { on("back").to "start" on("go").to "subber" } subber { subflow(action: "sub") on("end").to("end") } end() }

def subFlow() { subSubflowState { subflow(controller: "other", action: "otherSub") on("next").to("next") } … } }

You need to tell the test harness what to use for the "flow definition". This is done via overriding the abstract getFlow method:
抽象メソッドgetFlowをオーバライドすることにより、"フロー定義"を使っていることをテストハーネスに知らせる必要があります:

import grails.test.WebFlowTestCase

class ExampleFlowTests extends WebFlowTestCase { def getFlow() { new ExampleController().exampleFlow } … }

You can specify the flow id by overriding the getFlowId method, otherwise the default is test:
getFlowIdメソッドをオーバライドして、フローIDを指定することができます。指定しないならデフォルトとしてtestが使われます:
import grails.test.WebFlowTestCase

class ExampleFlowTests extends WebFlowTestCase { String getFlowId() { "example" } … }

If the flow under test calls any subflows, these (or mocks) must be registered before the calling the flow:
テストするフローがサブフローを呼び出す場合は、フローを呼び出す前にこれらフロー(もしくはモック)が登録済みでなければなりません:
protected void setUp() {
    super.setUp()

registerFlow("other/otherSub") { // register a simplified mock start { on("next").to("end") } end() }

// register the original subflow registerFlow("example/sub", new ExampleController().subFlow) }

Then you kick off the flow with the startFlow method:
次にstartFlowメソッドによりフローを開始します:

void testExampleFlow() {
    def viewSelection = startFlow()
    …
}

Use the signalEvent method to trigger an event:
イベントのトリガーを引くためにsignalEventを使います:

void testExampleFlow() {
    …
    signalEvent("go")
    assert "next" == flowExecution.activeSession.state.id
    assert "world" == flowScope.hello
}

Here we have signaled to the flow to execute the event "go" which causes a transition to the "next" state. In the example a transition action placed a hello variable into the flow scope.
ここで、"next"の状態への遷移を引き起こす"go"イベントを実行するためにフローにシグナルを送ります。この例では、遷移アクションがhello変数をフローのスコープに設定します。

h4. Testing Tag Libraries

タグライブラリのテスト

Testing tag libraries is simple because when a tag is invoked as a method it returns its result as a string (technically a StreamCharBuffer but this class implements all of the methods of String). So for example if you have a tag library like this:
タグライブラリのテストはタグがメソッドとして実行された結果として文字列(技術的にはStringの全てのメソッドを実装したStreamCharBufferとなります)が返されるので単純です。例えば、タグライブラリのテストはこのようになります:

class FooTagLib {

def bar = { attrs, body -> out << "<p>Hello World!</p>" }

def bodyTag = { attrs, body -> out << "<${attrs.name}>" out << body() out << "</${attrs.name}>" } }

The tests would look like:
テストはこのようになるでしょう:

class FooTagLibTests extends GroovyTestCase {

void testBarTag() { assertEquals "<p>Hello World!</p>", new FooTagLib().bar(null, null).toString() }

void testBodyTag() { assertEquals "<p>Hello World!</p>", new FooTagLib().bodyTag(name: "p") { "Hello World!" }.toString() } }

Notice that for the second example, testBodyTag, we pass a block that returns the body of the tag. This is convenient to representing the body as a String.
2番目のtestBodyTagの例を見てください。この例ではタグのボディを返すブロックを渡しています。これはタグ本体を文字列として表現するのに便利です。

h4. Testing Tag Libraries with GroovyPagesTestCase

GroovyPagesTestCaseを用いたタグライブラリのテスト

In addition to doing simple testing of tag libraries like in the above examples, you can also use the grails.test.GroovyPagesTestCase class to test tag libraries with integration tests.
上記例のように単純なタグライブラリのテストに加えて、インテグレーションテストでgrails.test.GroovyPagesTestCaseクラスを用いたタグライブラリのテストが可能です。

The GroovyPagesTestCase class is a subclass of the standard GroovyTestCase class and adds utility methods for testing the output of GSP rendering.
GroovyPagesTestCaseクラスは標準的なGroovyTestCaseクラスのサブクラスであり、GSPレンダリングの出力をテストするためのユーティリティメソッドが追加されています。

GroovyPagesTestCase can only be used in an integration test.
GroovyPagesTestCaseはインテグレーションテストの中だけで使えます。

For example, consider this date formatting tag library:
例えば、この日付フォーマットに関するタグライブラリを考えてみましょう:

import java.text.SimpleDateFormat

class FormatTagLib { def dateFormat = { attrs, body -> out << new SimpleDateFormat(attrs.format) << attrs.date } }

This can be easily tested as follows:
次のように簡単にテストできます:

class FormatTagLibTests extends GroovyPagesTestCase {
    void testDateFormat() {
        def template =
                '<g:dateFormat format="dd-MM-yyyy" date="${myDate}" />'

def testDate = … // create the date assertOutputEquals('01-01-2008', template, [myDate:testDate]) } }

You can also obtain the result of a GSP using the applyTemplate method of the GroovyPagesTestCase class:
GroovyPagesTestCaseクラスのapplyTemplateメソッドを使ったGSPの結果も得ることもできます:

class FormatTagLibTests extends GroovyPagesTestCase {
    void testDateFormat() {
        def template =
                '<g:dateFormat format="dd-MM-yyyy" date="${myDate}" />'

def testDate = … // create the date def result = applyTemplate(template, [myDate:testDate])

assertEquals '01-01-2008', result } }

h4. Testing Domain Classes

ドメインクラスのテスト

Testing domain classes is typically a simple matter of using the GORM API, but there are a few things to be aware of. Firstly, when testing queries you often need to "flush" to ensure the correct state has been persisted to the database. For example take the following example:
ドメインクラスのテストは一般的にはGORM APIを使った簡単なやり方で可能ですが、いくつか注意すべきことがあります。まず最初に、クエリをテストするときにはデータベースに正しい状態で確実に保存されるように、頻繁に"フラッシュ"をする必要があります。例えば、次の例を見てみましょう:

void testQuery() {
    def books = [
            new Book(title: "The Stand"),
            new Book(title: "The Shining")]
    books*.save()

assertEquals 2, Book.list().size() }

This test will fail because calling save does not actually persist the Book instances when called. Calling save only indicates to Hibernate that at some point in the future these instances should be persisted. To commit changes immediately you "flush" them:
このテストはsaveを呼び出していても、Bookインスタンスが呼び出されたときには実際には保存されていないので失敗するでしょう。saveを呼び出しても単にHibernateに未来のある時点でインスタンスが保存されるべきであることを示唆するだけです。ただちに変更をコミットするためには"フラッシュ"をします:

void testQuery() {
    def books = [
            new Book(title: "The Stand"),
            new Book(title: "The Shining")]
    books*.save(flush: true)

assertEquals 2, Book.list().size() }

In this case since we're passing the argument flush with a value of true the updates will be persisted immediately and hence will be available to the query later on.
このケースでは引数flushtrueを渡しているので、データの更新はただちに保存され、後のクエリでも利用可能になります。

12.3 ファンクショナルテスト

Functional tests involve making HTTP requests against the running application and verifying the resultant behaviour. The functional testing phase differs from the integration phase in that the Grails application is now listening and responding to actual HTTP requests. This is useful for end-to-end testing scenarios, such as making REST calls against a JSON API.

Grails does not ship with any support for writing functional tests directly, but there are several plugins available for this.
Grailsはファンクショナルテストを書くための直接的なサポートは提供しませんが、ファンクショナルテストのためのいくつかのプラグインが利用可能です。

Consult the documentation for each plugin for its capabilities.
それぞれのプラグインでできることはドキュメントを参照してください。

h4. Common Options

共通オプション

There are options that are common to all plugins that control how the Grails application is launched, if at all.
全てのプラグインに共通のGrailsアプリケーションの起動を制御するオプションがあります。

h5. inline
inlineオプション

The -inline option specifies that the grails application should be started inline (i.e. like run-app).
-inlineオプションが指定されるとGrailsアプリケーションがインライン起動されます(例えばrun-appのような)。

This option is implicitly set unless the baseUrl or war options are set
-inlineオプションは-baseUrl-warのどちらかが設定されていないと、暗黙的に有効になります

h5. war
warオプション

The -war option specifies that the grails application should be packaged as a war and started. This is useful as it tests your application in a production-like state, but it has a longer startup time than the -inline option. It also runs the war in a forked JVM, meaning that you cannot access any internal application objects.
-warオプションを指定すると、Grailsアプリケーションはwarファイルにパッケージ化した後に起動されます。このオプションはアプリケーションを実際にプロダクトと同じ状態でテストすることができるので便利です。しかし、-inlineオプションよりも起動に時間がかかります。また、warで起動するとフォークされたJVM上で実行されます。これは内部のオブジェクトにアクセスできないことを意味しています。

grails test-app functional: -war

Note that the same build/config options for the run-war command apply to functional testing against the WAR.
run-warコマンドで利用可能なビルドまたは設定オプションが、warファイルに対するファンクショナルテストでも使用できます。

h5. https
httpsオプション

The -https option results in the application being able to receive https requests as well as http requests. It is compatible with both the -inline and -war options.
-httpsオプションはhttpリクエストと同様にアプリケーションがhttpsリクエストを受け付けられるようにします。このオプションは-inline-warの両方のオプションと一緒に使うことができます。

grails test-app functional: -https

Note that this does not change the test base url to be https, it will still be http unless the -httpsBaseUrl option is also given.
-httpsオプションを使っていてもテストで使われる base url はhttpsにはなりません。-httpsBaseUrlをあわせて指定しない限り、httpのままとなります。

h5. httpsBaseUrl
httpsBaseUrlオプション

The -httpsBaseUrl causes the implicit base url to be used for tests to be a https url.
-httpsBaseUrlオプションを使えば暗黙的に設定されている base url がテスト時にhttpsのURLとして使われます。

grails test-app functional: -httpsBaseUrl

This option is ignored if the -baseUrl option is specified.
-httpsBaseUrlオプションは-baseUrlオプションが指定されると無視されます。

h5. baseUrl
baseUrlオプション

The baseUrl option allows the base url for tests to be specified.
-baseUrlオプションによりテスト実施時の base url を指定することができます。

grails test-app functional: -baseUrl=http://mycompany.com/grailsapp

This option will prevent the local grails application being started unless -inline or -war are given as well. To use a custom base url but still test against the local Grails application you must specify one of either the -inline or -war options.
-baseUrlオプションが指定されていると、ローカル環境でのGrailsアプリケーションを-inline-warを指定しないで起動することができなくなります。ローカル環境でのGrailsアプリケーションで base url を指定するには、必ず-inline-warのどちらかのオプションを指定する必要があります。