FC2ブログ

スポンサーサイト

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

[QUnit]deepEqualでクラスインスタンスとオブジェクトを比較してハマる

引き続きQUnitでテストしている。
QUnitにはdeepEqualというassertionがある。
配列やオブジェクトのメンバを再帰的に比較してくれるので役に立つ。

クラスのコンストラクタのテストで、以下のようなテストコードを作成した。
  var TestClass = function() {
    this.prop = 1;
  };
  test('TestClass', function(){
    var class1 = new TestClass();
    deepEqual(class1, {prop:1});
  });
メンバが同じオブジェクトなのに、deepEqualがfailedになった。しかもDiffが出ないので理由がわからない。

デバッガでたどって調べたところ、QUnit.equivの以下の箇所でfailedと判定されていた。
  // comparing constructors is more strict than using instanceof
  if ( a.constructor !== b.constructor) {
   return false;
  }
failedとなった理由は、同一クラスから生成されたインスタンスでないからだとわかった。

上記の箇所さえ通ればいいのではと思い、テストコードを変更
  var TestClass = function() {
    this.prop = 1;
  };
  test('TestClass', function(){
    var class1 = new TestClass();
    var object1 = {prop:1};
    object1.constructor = class1.constructor;
    deepEqual(class1, object1);
  });
だが再びfailed。理由はclass1.constructorが無いから。
class1.constructorは組み込みプロパティなので for ... in の対象にならず、QUnitでは抽出されない。

そこで、constructorプロパティをユーザー定義プロパティに上書きした。
  var TestClass = function() {
    this.prop = 1;
  };
  test('TestClass', function(){
    var class1 = new TestClass();
    var object1 = {prop:1};
    object1.constructor = class1.constructor;
    class1.constructor = class1.constructor;
    deepEqual(class1, object1);
  });
これで晴れてpassedになった。

めでたしめでたし・・・なのか?
QUnit.equivが変更されたらfailedになりそう。

<関連エントリ>
[QUnit]deepEqualでクラスインスタンスとオブジェクトを比較する方法
  クラスにメソッドがある場合、オブジェクトにメソッドもセットしないとdeepEqualをpassしない。
  オブジェクトのプロパティや配列中にあるクラスインスタンスを再帰的に探してメソッドを付与するプログラムを公開。
スポンサーサイト

コメント

コメントの投稿

非公開コメント

プロフィール

himax64

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

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