19

現在、いくつかの関数が内部にあるオブジェクトを返す関数があります。使用expect(...).toEqual({...})すると、それらの複雑なオブジェクトと一致しないようです。関数またはクラス(入力型ファイルから)を持つオブジェクトはFile、それができません。これを克服する方法は?

4

5 に答える 5

17

アンダースコア_.isEqual()関数を試してください。

expect(_.isEqual(obj1, obj2)).toEqual(true);

それが機能する場合は、カスタムマッチャーを作成できます:

this.addMatchers({
    toDeepEqual: function(expected) {
        return _.isEqual(this.actual, expected);
    };
});

次に、次のような仕様を記述できます。

expect(some_obj).toDeepEqual(expected_obj);
于 2013-01-26T20:38:25.873 に答える
13

Vlad Magdalinがコメントで指摘しているように、オブジェクトをJSON文字列にすることで、オブジェクトをそのままの深さにすることができ、関数とFile/FileListクラスを作成できます。もちろん、toString()関数ではなく、単に「関数」と呼ぶこともできます。

function replacer(k, v) {
    if (typeof v === 'function') {
        v = v.toString();
    } else if (window['File'] && v instanceof File) {
        v = '[File]';
    } else if (window['FileList'] && v instanceof FileList) {
        v = '[FileList]';
    }
    return v;
}

beforeEach(function(){
    this.addMatchers({
        toBeJsonEqual: function(expected){
            var one = JSON.stringify(this.actual, replacer).replace(/(\\t|\\n)/g,''),
                two = JSON.stringify(expected, replacer).replace(/(\\t|\\n)/g,'');

                return one === two;
            }
    });
});

expect(obj).toBeJsonEqual(obj2);
于 2013-01-27T02:35:21.177 に答える
5

誰かが私のようにnode.jsを使用している場合、次の方法は、すべての関数を無視して単純なプロパティを比較することだけに関心があるときに、Jasmineテストで使用する方法です。このメソッドには、シリアル化する前にオブジェクトのプロパティを並べ替えるために使用されるjson-stable-stringifyが必要です。

使用法:

  var stringify = require('json-stable-stringify');

  var obj1 = {
    func: function() {
    },
    str1: 'str1 value',
    str2: 'str2 value',
    nest1: {
    nest2: {
        val1:'value 1',
        val2:'value 2',
        someOtherFunc: function() {
        }
      }
    }
  };

  var obj2 = {
    str2: 'str2 value',
    str1: 'str1 value',
    func: function() {
    },
    nest1: {
      nest2: {
        otherFunc: function() {
        },
        val2:'value 2',
        val1:'value 1'
      }
    }
  };

  it('should compare object properties', function () {
    expect(stringify(obj1)).toEqual(stringify(obj2));
  });
于 2015-02-25T22:48:33.573 に答える
4

@Vlad Magdalinの答えを拡張して、これはJasmine2で機能しました。

http://jasmine.github.io/2.0/custom_matcher.html

beforeEach(function() {
  jasmine.addMatchers({
    toDeepEqual: function(util, customEqualityTesters) {
      return {
        compare: function(actual, expected) {
          var result = {};
          result.pass = _.isEqual(actual, expected);
          return result;
        }
      }
    }
  });
});

Karmaを使用している場合は、それをスタートアップコールバックに入れます。

callback: function() {
  // Add custom Jasmine matchers.
  beforeEach(function() {
    jasmine.addMatchers({
      toDeepEqual: function(util, customEqualityTesters) {
        return {
          compare: function(actual, expected) {
            var result = {};
            result.pass = _.isEqual(actual, expected);
            return result;
          }
        }
      }
    });
  });

  window.__karma__.start();
});
于 2015-06-06T03:19:38.177 に答える
2

これが私がJasmine 2構文を使ってそれをした方法です。

でcustomMatchersモジュールを作成しました../support/customMatchers.js(モジュールを作成するのが好きです)。

"use strict";

/**
 *  Custom Jasmine matchers to make unit testing easier.
 */
module.exports = {
  // compare two functions.
  toBeTheSameFunctionAs: function(util, customEqualityTesters) {
    let preProcess = function(func) {
      return JSON.stringify(func.toString()).replace(/(\\t|\\n)/g,'');
    };

    return {
      compare: function(actual, expected) {
        return {
          pass: (preProcess(actual) === preProcess(expected)),
          message: 'The functions were not the same'
        };
      }
    };
  }
}

これは、私のテストで次のように使用されます。

"use strict";

let someExternalFunction = require('../../lib/someExternalFunction');
let thingBeingTested = require('../../lib/thingBeingTested');

let customMatchers = require('../support/customMatchers');

describe('myTests', function() {

  beforeEach(function() {
    jasmine.addMatchers(customMatchers);

    let app = {
      use: function() {}
    };

    spyOn(app, 'use');
    thingBeingTested(app);
  });

  it('calls app.use with the correct function', function() {
    expect(app.use.calls.count()).toBe(1);
    expect(app.use.calls.argsFor(0)).toBeTheSameFunctionAs(someExternalFunction);
  });

});
于 2015-11-12T23:14:32.700 に答える