Sails アプリケーションのモデル、コントローラー、およびサービスで単体テストをセットアップしています。User モデルをテストしているときに、紛らわしい問題に遭遇しました。の抜粋User.js
:
module.exports = {
attributes: {
username: {
type: 'string',
required: true
},
[... other attributes...] ,
isAdmin: {
type: 'boolean',
defaultsTo: false
},
toJSON: function() {
var obj = this.toObject();
// Don't send back the isAdmin attribute
delete obj.isAdmin;
delete obj.updatedAt;
return obj;
}
}
}
以下は私test.js
のもので、モカで実行することを意図しています。pluralize
blueprints config でフラグをオンにしたことに注意してください。また、Ember Data に準拠したブループリントを作成するために、Sails-ember-blueprintsを使用します。したがって、私のリクエストは次のようになります{user: {...}}
。
// Require app factory
var Sails = require('sails/lib/app');
var assert = require('assert');
var request = require('supertest');
// Instantiate the Sails app instance we'll be using
var app = Sails();
var User;
before(function(done) {
// Lift Sails and store the app reference
app.lift({
globals: true,
// load almost everything but policies
loadHooks: ['moduleloader', 'userconfig', 'orm', 'http', 'controllers', 'services', 'request', 'responses', 'blueprints'],
}, function() {
User = app.models.user;
console.log('Sails lifted!');
done();
});
});
// After Function
after(function(done) {
app.lower(done);
});
describe.only('User', function() {
describe('.update()', function() {
it('should modify isAdmin attribute', function (done) {
User.findOneByUsername('skippy').exec(function(err, user) {
if(err) throw new Error('User not found');
user.isAdmin = false;
request(app.hooks.http.app)
.put('/users/' + user.id)
.send({user:user})
.expect(200)
.expect('Content-Type', /json/)
.end(function() {
User.findOneByUsername('skippy').exec(function(err, user) {
assert.equal(user.isAdmin, false);
done();
});
});
});
});
});
});
User.isAdmin への書き込みアクセスを禁止するポリシーを設定する前に、user.isAdmin 属性がこのリクエストによって更新されることを期待しています。テストを実行する前に、ユーザーの isAdmin フラグが true に設定されています。テストを実行すると、フラグが更新されていないことが示されます。
1) User .update() should modify isAdmin attribute:
Uncaught AssertionError: true == false
クライアント側で実行される次の QUnit テストは isAdmin 属性を更新するため、これはさらに不可解です。ただし、更新されたかどうかはわかりません。
var user;
module( "user", {
setup: function( assert ) {
stop(2000);
// Authenticate with user skippy
$.post('/auth/local', {identifier: 'skippy', password: 'Guru-Meditation!!'}, function (data) {
user = data.user;
}).always(QUnit.start);
}
, teardown: function( assert ) {
$.get('/logout', function(data) {
});
}
});
asyncTest("PUT /users with isAdmin attribute should modify it in the db and return the user", function () {
stop(1000);
user.isAdmin = true;
$.ajax({
url: '/users/' + user.id,
type: 'put',
data: {user: user},
success: function (data) {
console.log(data);
// I can not test isAdmin value here
equal(data.user.firstName, user.firstName, "first name should not be modified");
start();
},
error: function (reason) {
equal(typeof reason, 'object', 'reason for failure should be an object');
start();
}
});
});
mongoDB コンソールで:
> db.user.find({username: 'skippy'});
{ "_id" : ObjectId("541d9b451043c7f1d1fd565a"), "isAdmin" : false, ..., "username" : "skippy" }
さらに不可解なのは、コメントアウトするdelete obj.isAdmin
とUser.toJSON()
mocha テストに合格することです!
だから、私は疑問に思います:
- Waterline モデルの toJSON() メソッドは、出力フィルタリングにのみ使用されますか? または、update() などの書き込み操作に影響がありますか。
- この問題はスーパーテストに関連している可能性がありますか? 私の QUnit テストの jQuery.ajax() は isAdmin フラグを変更するため、スーパーテスト リクエストが変更しないのは非常に奇妙です。
どんな提案でも本当に感謝しています。