5

メタクラスを使用して grails 1.3.7 でモックされたプライベート メソッドがありますが、grails バージョンを 2.2.4 にアップグレードしたため、同じモックが失敗します。

テストするメソッドにプライベート メソッドへの呼び出しがあります

   private def MyPrivateMeth1(def arg1, def arg2) {
...
}

嘲笑はこのようなものです

MyController.metaClass.private.MyPrivateMeth1 = { a, b ->
... 
}
4

4 に答える 4

7

@TestFor アノテーションを使用してみてください。これにより、コントローラー変数が得られます。次に、そのメタクラスを変更し、Kamil Mikolajczyk と araxn1d の提案を組み込むことができます。したがって、テスト全体はおそらく次のようになります。

@TestFor(MyController) 
class MyControllerTests { 

    setup() {
        controller.metaClass.MyPrivateMeth1 = {def arg1, def arg2 -> 
            //you can make your mocked method return whatever you wish here
            return [key1: "foo", key2: "bar"] 
        }
    }
    void testForSomething() {
        //Some code here that invokes an action or two in your controller which in turn invokes the private method
    }
}

コントローラー内の実際のプライベート メソッドとまったく同じように、モック メソッドの引数に def (または String、Long、または使用する任意の宣言) があることを確認してください。そうしないと、テストはクラスの通常のプライベート メソッドを最初に使用しようとします。.

Spock での同様のテストを次に示します。

import spock.lang.Specification
import spock.lang.Unroll
import grails.test.mixin.*
import org.junit.*
@TestFor(MyController) 
class MyControllerSpec {

    def "test that thing"() {
        setup:
            controller.metaClass.MyPrivateMeth1 = {def arg1, def arg2 -> return someOutput }
        expect:
            controller.someAction() == expectedRender
        where: 
            someOutput                              | expectedRender
            [key1: "foo", key2: "bar"]              | "expected render from controller"
    }
}
于 2013-11-26T22:09:59.020 に答える
1

クロージャー引数の型を宣言する必要があるようです (その引数に実際の型がある場合は 100% です。たとえばLong、def についてはわかりませんが、試す必要があります):

MyController.metaClass.MyPrivateMeth1 = { def a, def b -> ... }
于 2013-09-23T09:14:05.307 に答える
0

単体テストでは、プライベート メソッドに Reflection を使用しました。これに似たものが機能するはずです...

Method method = BehaviourService.getDeclaredMethod("behaviourValidConstraints",User.class,Behaviour.class)
method.setAccessible(true)
boolean valid = ((Boolean)method.invoke(service, user,b)).booleanValue()

最初に getDeclaredMethod で名前とパラメーターの型を設定してメソッドを取得し、アクセス可能に設定して、最後にメソッドとパラメーターを持つオブジェクトを渡す method.invoke で呼び出します。結果はオブジェクトなので、キャストする必要があります。

もっと良い解決策があるに違いないことは知っていますが、これは私が見つけた唯一の解決策です

編集:申し訳ありませんが、上記はプライベートメソッドを呼び出すためのものです。やる前にプライベートメソッドを嘲笑したと思います...

MyController.metaClass.myPrivateMeth1 { a, b ->
... 
}

あなたが書いたのと同じですが、.private と = 記号はありません。また、Kamil が言ったように、メソッド名については Java の命名規則に従う必要があります...

于 2013-09-23T06:46:31.087 に答える