現在、grails 1.3.7 アプリを 2.1.0 にアップグレードしており、テストしたいフィルターのセットがあります。フィルターをテストするためのgrails ドキュメントが、フィルターの単体テストがサポートされるようになったことを示唆しているように (/推奨されますか? 機能部分で言及されていますが、例が見つかりません)、フィルターの既存の統合テストを単体テストに変換しようとしています。 .
ただし、このフィルターを適切に「モック化」するのに苦労していますdependsOn
/少なくともservice
、フィルターが注入されているいくつかの s のモックを適切に実装します。
package com.example
import ... // excluded for brevity
class MyFilters {
GrailsApplication grailsApplication
SomeService someService
def dependsOn = [MyOtherFilters]
def filters = {
all(controller: 'controllerToExclude', invert: true) {
before = {
if (grailsApplication.config.someConfigProperty) {
def someProperty = request.getAttribute('MY_ATTRIBUTE')
if (someProperty = someService.someMethod()) {
redirect(url: someService.getNewUrl(session))
return false
}
}
return true
}
}
}
}
そして他のフィルター:
package com.example
class MyOtherFilters {
SomeOtherService someOtherService
def filters = {
all(controller: '*', action: '*') {
before = {
def foo
if (params[MY_ATTRIBUTE]) {
foo = params[MY_ATTRIBUTE]
someOtherService.setMyAttribute(sitePreference, request)
}
if (!foo) {
foo = someOtherService.getMyAttribute(request)
}
if (foo) {
request.setAttribute('MY_ATTRIBUTE', foo)
}
return true
}
}
}
}
これは、私が使用している 2 つのフィルターの非常に骨組みを簡略化したバージョンです (興味がある方は、モバイルとデスクトップの設定を読み取り、その設定に基づいてフィルター処理を行ってください)。
したがって、私が書いているテストはおおよそ次のようになります。
package com.example
import grails.test.mixin.TestFor // ... etc more imports here
@TestFor(SomeController)
@Mock(MyFilters) // TODO what goes here???
class MyFiltersTests {
static final IPAD_USER_AGENT = 'Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3'
static final NON_MOBILE_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.12011-10-16 20:23:00'
void testFilterRedirects() {
grailsApplication.config.someConfigProperty = true
// actual filter logic acts on this user-agent through some service calls, would like to mock it out though
request.addHeader("user-agent", IPAD_USER_AGENT)
def result
withFilters(action: "index") {
result = controller.index()
}
//assertSomething on result perhaps
assertEquals "myExpectedRedirectUrl", response.redirectedUrl
}
}
このコードのままでは、MyFilters
コードを実行することすらできません。依存フィルターをモッキング ala に追加してみました:
@Mock([MyFilters, MyOtherFilters])
しかし、その後、SomeOtherService
メソッドが定義されていないという問題に遭遇し、それらのメソッドを適切にモックする方法が見つかりませんでした (フィルターにサービスモックを設定するにはどうすればよいですか?コントローラーまたはサービスで実行できるdef myMock = mockFor(SomeOtherService)
かcontroller.someOtherService = myMock.createMock()
、または何か並べ替えますがwithFilters
、ドキュメントが使用を提案しているこのブロックでフィルターのサービスを設定する方法が見つかりません。
理想的には、someService
andに関係するものはすべてモックアウトしMyOtherFilters
、このフィルターでテストを書くだけですが、フィルターのテストで何が可能かはわかりません。
ここまでお進みいただきありがとうございます。