2017-08-03 10 views
1

以下の関数で作業するための基本単位テストを作成しようとしていますが、それを動作させることはできません。適切なnpm-expressレスポンスのようなものが返されたことをどのようにテストするのですか?Mongooseクエリを返す関数を適切にテストする方法

私は既にUsing Sinon to stub chained Mongoose callshttps://codeutopia.net/blog/2016/06/10/mongoose-models-and-unit-tests-the-definitive-guide/、およびUnit Test with Mongooseを見ましたが、それでも分かりません。私の現在の最良の推測とその結果のエラーは、テストする関数の下にあります。可能であれば、私はモカ、シノン、チャイ・エスペクト以外のものを使用したくない(つまり、シオン・モンゴース、期待通りのものではない)。私がここで/他に何をテストするべきかのような他のアドバイスは、大歓迎です。ありがとうございました!

機能をテストする:

function testGetOneProfile(user_id, res) { 
    Profiles 
    .findOne(user_id) 
    .exec() 
    .then((profile) => { 
     let name = profile.user_name, 
     skills = profile.skills.join('\n'), 
     data = { 'name': name, 'skills': skills }; 
     return res 
     .status(200) 
     .send(data); 
    }) 
    .catch((err) => console.log('Error:', err)); 
} 

私の現在の最良の推測ユニットテスト:

const mongoose = require('mongoose'), 
     sinon = require('sinon'), 
     chai  = require('chai'), 
     expect = chai.expect, 
     Profile = require('../models/profileModel'), 
     foo  = require('../bin/foo'); 

mongoose.Promise = global.Promise; 

describe('testGetOneProfile', function() { 
    beforeEach(function() { 
    sinon.stub(Profile, 'findOne'); 
    }); 
    afterEach(function() { 
    Profile.findOne.restore(); 
    }); 

    it('should send a response', function() { 
    let mock_user_id = 'U5YEHNYBS'; 
    let expectedModel = { 
     user_id: 'U5YEHNYBS', 
     user_name: 'gus', 
     skills: [ 'JavaScript', 'Node.js', 'Java', 'Fitness', 'Riding', 'backend'] 
    }; 
    let expectedResponse = { 
     'name': 'gus', 
     'skills': 'JavaScript, Node.js, Java, Fitness, Riding, backend' 
    }; 
    let res = { 
     send: sinon.stub(), 
     status: sinon.stub() 
    }; 
    sinon.stub(mongoose.Query.prototype, 'exec').yields(null, expectedResponse); 
    Profile.findOne.returns(expectedModel); 

    foo.testGetOneProfile(mock_user_id, res); 

    sinon.assert.calledWith(res.send, expectedResponse); 
    }); 
}); 

テストメッセージ:これはトリッキーなのビットです

1) testGetOneProfile should send a response: 
    TypeError: Profiles.findOne(...).exec is not a function 
     at Object.testGetOneProfile (bin\foo.js:187:10) 
     at Context.<anonymous> (test\foo.test.js:99:12) 
+0

あなたの 'Profile'モジュールで' findOne'関数が定義されているかどうかチェックする必要があります。おそらくあなたはそれを 'findone'と定義したでしょう。 – Mekicha

+0

ドキュメントから: 'var stub = sinon.stub(object、" method ");' 'object.method'をスタブ関数に置き換えます。プロパティがまだ関数でない場合は、例外がスローされます。 – Mekicha

+0

@Mekicha 'findOne'関数は' mongoose'で定義されているので、 'Profile'モジュールから委譲されるべきです。問題は(私は思う!)約束の構造です。このエラーは 'findOne'ではなく' exec() 'にスローされます。他のアイデア? –

答えて

2

シナリオ。ここでの問題は、テストのfindOneスタブがモデルオブジェクトを返すことです。代わりに、プロパティ値execを含むオブジェクトを返す必要があります。これは最終的にモデル値に解決される約束返す関数です...はい、前述のように、それは少しトリッキーです:)

このような何か:

const findOneResult = { 
    exec: sinon.stub().resolves(expectedModel) 
} 

Profile.findOne.returns(findOneResult); 

あなたはまた、

//if we set up the stub to return the res object 
//it returns the necessary func 
res.status.returns(res); 
機能を含むオブジェクトを返すレスポンス・オブジェクトに status機能を持っている必要があります

私はあなたがテストで他の何かを変更する必要はないと思うし、それはそのように動作するかもしれません。スタブに解決関数が存在するようにするには、sinon 2.0以降が必要です(または、sinon 1.xで約束されたsinonを使用することができます)。

このポストは、対処方法 https://codeutopia.net/blog/2016/05/23/sinon-js-quick-tip-how-to-stubmock-complex-objects-such-as-dom-objects/

+0

初期の問題を修正しましたが、Expressの 'res'オブジェクトをどのようにスタブ(または?)するのか分かりません。 'res.send(200)'をスタブすることはできますが、 '.send(data)'部分はスタブすることはできません。エラー:TypeError:res.status(...)。sendは関数ではありません。リンクした投稿は参考になりましたが、私はまだ立ち往生しています! –

+0

@PeterMartinson同様の問題です。 'res.status'関数は、' send'関数を含むオブジェクトを返す必要があります。私はこれの答えを更新しました –

関連する問題