FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[QUnit]deepEqualでクラスインスタンスとオブジェクトを比較する方法

この方法は、2011-05-16 commit版のQUnitで確認しています。
QUnit.equivの実装が変わるとdeepEqualをpassしなくなる恐れがありますので注意してください。

QUnitには、deepEqualというオブジェクトの比較に便利なassertionがある。
以下のように、あらかじめ用意した結果との比較が簡単にできる。
test('testfunc()のテスト', 1, function() {
  // 予想される結果
  var expobj = [
    {prop1: 1, prop2: 1},
    {prop1: ['a', 12, {a: null, b: 15}], prop2: null}
  ];

  var testobj = testfunc();
  deepEqual(testobj, expobj, 'compare testobj with expobj');
});

しかし、クラスインスタンスとオブジェクトを比較する場合、オブジェクトにメソッドとコンストラクタをセットしないとdeepEqualをpassしない。
そこで、メソッドとコンストラクタをセットするのに便利なプログラムを作成した。
setmethod.js(文字コードはUTF-8)
提供している関数はmiqtutl.setmethod()だけ。
  var rtn = miqtutl.setmethod(chkobj, targetobj);
で、chkobjのメソッドとコンストラクタををtargetobjにセットできる。

関数からはエラーメッセージの配列がreturnされるので、
  var rtn = miqtutl.setmethod(chkobj, targetobj);
  deepEqual(rtn, [], 'no error message');
とすることで、きちんとセットできたことを確認できる。
エラーメッセージは、メソッド付与対象のオブジェクトが存在しない場合や、メソッドと同名のプロパティが既に存在している場合などに出力される。
setmethod1.png
deepEqual(rtn, [])でリターン値をチェックすると、エラーの場合上のように表示される。

miqtutl.setmethod()を使って、以下のようにクラスインスタンスとオブジェクトとを比較できる。
// テスト対象のクラス
var TestClass1 = function(arg1, arg2) {
  this.prop1 = [];
  for (var i = 0; i < 3; i++) {
    this.prop1[i] = new TestClass2(i, arg1);
  }
  this.prop2 = {};
  this.prop2.sub1 = arg2;
  this.prop2.sub2 = new TestClass2('sub2', arg2);
};
var TestClass2 = function(arg1, arg2) {
  this.prop3 = arg1;
  this.prop4 = arg2;
};
TestClass2.prototype.test = function() {
  return this.prop3;
};

test('TestClass1のconstructorのテスト', 2, function() {
  // 予想される結果
  var expobj = {
    prop1: [{prop3: 0, prop4: 'a'}, {prop3: 1, prop4: 'a'},
        {prop3: 2, prop4: 'a'}],
    prop2: {sub1: 'b', sub2: {prop3: 'sub2', prop4: 'b'}}
  };
  // クラスインスタンスを生成し、expobjにクラスのメソッドとコンストラクタをセット
  var clsins = new TestClass1('a', 'b');
  var rtn = miqtutl.setmethod(clsins, expobj);
  deepEqual(rtn, [], 'no error message');
  // クラスインスタンスと予想される結果とを比較
  deepEqual(clsins, expobj, 'compare clsins with expobj');
});

特記事項
・miqtutl.setmethod()は、メソッドとコンストラクタをコピーしているのではなく、参照をセットしているだけ。
・メソッドをセットしてもプロパティの順序が異なるので、deepEqualはpassしてもDiffは出力される。
・再帰の深度が10になると例外がthrowされる。setmethod.jsのmaxDepthの値を変えることで、最大深度を変更できる。

以上。
予想される結果を作成するために、オブジェクトのダンプをテキスト出力するプログラムも作ったので、そのうち公開するかもしれない。
(公開しました → [QUnit]オブジェクトのダンプを取って内容を比較する
スポンサーサイト

コメント

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

コメントの投稿

非公開コメント

プロフィール

himax64

Author: 南西
30代後半の無職です。
就活もせずダラダラ生きてます。
作ったもの

最新記事
人気記事
検索フォーム
カテゴリ
月別アーカイブ
最新コメント
最新トラックバック
RSSリンクの表示
QRコード
QRコード
カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。