4

私はいくつかのテストを書きたいコア機能の多くを Java オブジェクト (JavaLoader 経由で作成) に大きく依存している cfc を持っていますが、これを行うための最良の方法がわかりません。これは、java オブジェクトである instance.note を使用してテストを書きたいメソッドの例です。

<cffunction name="getNotes" returntype="Array" access="public" output="false" hint="I return a list of a users notebooks" >
    <cfargument name="maxCount" type="numeric" required="false" default="9999" hint="The maximum number of notes to get" />
    <cfscript>
        if(arguments.maxCount)
            return instance.note.listNotes(maxCount);
        else
            return instance.note.listNotes();
    </cfscript>
</cffunction>

私が考えたことの 1 つは、同じメソッド名と同様の戻り値を持つスタブ CFC を作成し、そのスタブをモックして注入することですか?

4

3 に答える 3

3

結果、つまりメモの配列に意味のあるアサーションを書くことはできませんか? そのコードを見て、私がテストする唯一のことは、a) maxCount を渡すとき、結果の配列はそのサイズを尊重しますか? b) maxCount がない場合、音符のリストは期待どおりの長さですか? それがあなたのコードが行うすべてだからです。基礎となるJavaオブジェクトのコードではなく、あなたのコードをテストします。

于 2011-07-14T12:26:38.730 に答える
2

Java オブジェクトに依存する CF 関数の単体テストが必要になったとき (私たちは多くのことを行いました)、Mockitoを使用して Java オブジェクトをモックしました。

したがって、このコード スニペットが理にかなっていることを願って、これを行ってからほぼ 1 年が経ちました。

<cfcomponent displayname="TestWhatever" extends="mxunit.framework.TestCase" output="false">

    <cffunction name="setUp" access="public" returntype="void">
      <cfscript>
        // named it mk for keeping it short
        variables.mk = createObject("java","org.mockito.Mockito");

        //Create the mock object
        variables.mockNote = mk.mock(createObject("java","com.company.whatever.note").getClass());

        // Mock Data
        fullList = {whatever listNotes() returns}
        partialList3 = {whatever listNotes(3) returns}

        //some common mocking
        mk.when(variables.mockNote.listNotes()).thenReturn(fullList);
        mk.when(variables.mockNote.listNotes(mk.eq(3))).thenReturn(partialList3);
        mk.when(variables.rootOrgObj.guid()).thenReturn("root");

        // Assign the mock object to where your CFC expects it.
        instance.note = variables.mockNote
      </cfscript>
    </cffunction>

</cfcomponent>

そうは言っても、サンプル関数が本物の場合、それを単体テストしても意味がありません。それは単に何もしていませんが、Java オブジェクトへのプロキシです。テストする重要なロジックはありません。

あなたはcfargumentにデフォルトを持っているので、それは常に存在します(繰り返しますが、私がCFを行ってから1年が経ちました)ので、ガードステートメントは必要ありません-最初のコードパスは常に呼び出されます、指定されている場合は渡された maxCount、指定されていない場合は 9999 。

于 2011-07-14T20:47:14.687 に答える
0

私はエドワードの答えを取り、それを次のように実装しました:

JavaLoader ライブラリを使用して、mockito オブジェクトを作成しました。variables.cfEvernote = "";

variables.classLoader = createObject("component", "resources.JavaLoader").
    init(["#expandPath('../lib/mockito-all-1.8.5.jar')#",
          "#expandPath('../lib/CFEvernote.jar')#",                                                                      
          "#expandPath('../lib/libthrift.jar')#",
          "#expandPath('../lib/evernote-api-1.18.jar')#"]);  

variables.mockito = variables.classLoader.create("org.mockito.Mockito").init();

次に、munit テストの setup メソッドで、新しいモック Java オブジェクトを作成します。

<cffunction name="setUp" access="public" output="false" returntype="void">
<cfscript>
variables.cfEvernote = createObject("component","com.714studios.cfevernote.CFEvernote").
                        Init(variables.configArray[1],variables.configArray[2],
                             "sandbox.evernote.com",
                             "http://localhost/cfevernote/callback.cfm"
                             "#ExpandPath('../lib')#");

variables.mockCFEvernote = variables.mockito.mock(variables.classLoader.create("com.sudios714.cfevernote.CFEvernote").
                           Init("123","S1","232","sandbox.evernote.com","mock").getClass());

variables.cfEvernote.setCFEvernote(mockCFEvernote);
</cfscript>     

次に、私のテストでは、そのようにモックの動作を作成します。

<cffunction name="test..."  returntype="void" access="public" output="false" >
<cfscript>
    var notebooks = ""; 
    var expected = 12;
    var i = 0;
    var retArray = createObject("Java","java.util.ArrayList");
    var actual = "";

    for(i = 1; i lte 12; i = i + 1){
        retArray.Add("");
    }

    variables.mockito.when(mockCFEvernote.listNotebooks(12)).thenReturn(retArray);

    notebooks = variables.cfEvernote.getNotebooks(12); 

    actual = arrayLen(notebooks);

    assertEquals(expected,actual);
</cfscript>

これについては、 http://blog.bittersweetryan.com/2011/07/unit-testing-coldfusion-components-that.htmlでもう少し詳しくブログにも書いています。

于 2011-07-19T12:25:20.133 に答える