7

Springセキュリティ コア プラグインサービスを注入する抽象クラスを拡張するドメイン クラスがあります。

class Extra extends WithOwner {
    String name
}

abstract class WithOwner {
    transient springSecurityService
    User user

    def getCurrentUser() {
        return springSecurityService.currentUser
    }

    def beforeValidate() {
        if(!user) {
             user = getCurrentUser()
        }
    }

    Boolean isLoggedUserTheOwner(){
        return (user?.id == getCurrentUser()?.id)
    }
}

コントローラーのテストを実装したい。

@TestFor(ExtraController)
@Mock([Extra, User, UserRole, Role])
class ExtraControllerTests {

    void testEdit() {
        def utils = new TestUtils()
        def user1 = utils.saveUser1()

        populateValidParams(params)
        def extra = new Extra(params)
        extra.user = user1
        assert extra.save() != null

        params.id = extra.id


        def model = controller.edit() // Line 69
        assert model.extraInstance == extra
    }
}

上記のテストを実行すると、次のようになります。

test-app ExtraController.testEdit --unit --echoOut | 1 つの単体テストを実行しています... 1/1 --testEdit からの出力-- | 失敗: testEdit(com.softamo.movi​​lrural.ExtraControllerTests) | java.lang.NullPointerException: com.softamo.movi​​lrural.WithOwner.getCurrentUser(WithOwner.groovy:8) で null オブジェクトのプロパティ 'currentUser' を取得できません com.softamo.movi​​lrural.WithOwner.isLoggedUserTheOwner(WithOwner.groovy:18) でcom.softamo.movi​​lrural.ExtraController.edit(ExtraController.groovy:39) で com.softamo.movi​​lrural.ExtraControllerTests.testEdit(ExtraControllerTests.groovy:69) | 1 つの単体テストが完了し、853 ミリ秒で 1 つが失敗しました

次のようにセキュリティ サービスをモックしようとしましたが、成功しませんでした。

Extra.metaClass.springSecurityService = new MockSpringSecurityService(user1)

またはメソッドを嘲笑することさえあります

Extra.metaClass.getCurrentUser = { return user1 }

この問題を回避するにはどうすればよいでしょうか。

4

3 に答える 3

2

Grails 2.x は、'defineBeans' クロージャーを使用したテスト環境用の Spring Bean の定義をサポートしています。コントローラーなどで依存性注入をサポートしていますが、ドメイン オブジェクトでも機能するかどうかはわかりません。理論的には、ドメイン オブジェクト/コントローラー/サービス間で一貫性があるはずです。

http://grails.org/doc/latest/guide/single.html#testing - 「Spring Bean のテスト」セクションを参照してください。

于 2012-04-23T09:51:29.233 に答える
1

これは機能するはずです:

controller.springSecurityService = new SpringSecurityService()

このサービスでgetCurrentUserメソッドをモックする場合:

controller.springSecurityService.metaClass.getCurrentUser = { -> return user1 }

上記の行で省略できるかどうかわからない->ので、テストしてください。使用後または別のテストケースの前にこのモックメソッドをクリアする場合は、次を使用します。

controller.springSecutiryService.metaClass = null
于 2012-04-23T07:31:49.857 に答える
1

この問題に関する素晴らしい記事を見つけました: Inject springSecurityService Into Grails Domain Class for Controller Unit Testing

于 2013-08-12T13:55:32.170 に答える