2

我正在我的 Sails 应用程序的模型、控制器和服务上设置单元测试。在测试我的用户模型时,我偶然发现了一个令人困惑的问题。摘录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,旨在与 mocha 一起运行。请注意,我在蓝图配置中打开了pluralize标志。此外,我使用sails-ember-blueprints来获得符合Ember Data 的蓝图。所以我的请求必须看起来像{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 属性,尽管它无法判断它是否已更新,因为我从 User.toJSON() 中的有效负载中删除了 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 标志,所以超测试请求没有修改是很奇怪的。

任何建议都非常感谢。

4

0 回答 0