使用supertest、mocha和models进行回环测试

11
Google groups关于弃用loopback-testing的帖子中,有一个问题询问如何提供一个适当的示例来演示如何在没有loopback-testing的情况下进行测试。该帖讨论了使用supertest的方法。
以下是我的一个尝试,结合了Mocha、supertest和模型(来源于app.js)。当我单独运行该文件时,结果非常好。但如果我再有另一个测试文件(test-teacher.js),那么第一个测试文件(test-student.js)就会以我无法描述的奇怪方式失败。
我是否遗漏了什么,或者像我下面所用的那样不能使用模型?
describe('/Student', function () {

    var server = require('../server/server')
    var loopback = require('loopback')
    var supertest = require('supertest')
    var request = require('supertest')(server)

    var dataSource = server.dataSource('db', {adapter: 'memory'})

    var Student = dataSource.define('Student', {
        'id': Number,
        'points': Number
    });

    beforeEach(function () {
        Student.updateOrCreate({id: 1, points: 5000});
    })


    it('Post a new student', function (done) {
        request.post('/api/Students').send({points: 5000}).expect(200, done)

    })


})

1
你从哪里获取 dataSource 变量的?无论如何,在同一测试运行中的多个文件都共享内存,这意味着您还共享内存模型定义和数据。我猜你在其中某个地方启动了 LB 应用程序,是吗?你需要确保关闭它,但数据可能仍然存在。那就是我的猜测。 - Jordan Kasper
非常好的发现。剪切和粘贴错误。添加了 dataSource 声明。关于启动 LB 应用程序,我不会显式地执行它。可以使用 mocha test/test-student.js 运行上述代码。然后我可以使用 mocha test 运行所有测试。通过定义与服务器的请求,它调用 LB。 - Dakotah North
所以...事实证明在第二个文件test-teacher.js中我也定义了Student。当我在test-teacher.js中注释掉Student时,上面的测试就可以工作了。然后显然test-teacher.js中的测试失败了,因为它现在不知道Student的存在。 - Dakotah North
2个回答

15

根据 jakerella 对上一个答案的反馈,我更改了上面的代码,这样我就不必在代码中重新定义模型了(感谢 jakerella!)

使用下面的代码,我能够在单个套件中运行多个不同模型的所有测试,使用 npm test 没有任何失败。

因为我只对单个订单感兴趣... 监听和关闭是不必要的。我怀疑如果我正在测试创建的模型的整体实例,它将变得必要。

describe('/Student', function () {

    var server = require('../server/server')
    var request = require('supertest')(server)
    var expect = require('expect.js')

    var Student 

    before(function() {
        Student = server.models.Student    
    })

    beforeEach(function (done) {
        Student.upsert({id: 1, points: 5000}, function() { done() })
    })    

    it('Post a new student', function (done) {
        request.post('/api/Students').send({points: 5000}).expect(200, done)
     })
})

2
除了我刚刚修复的一些错别字之外,这实际上非常有帮助。特别是 var request = require('supertest')(server),这样在测试中你可以简单地执行 request.post('/api/Students') - Christiaan Westerbeek

8

我想把这个问题放入答案中......第一个问题是未定义的 dataSource 变量,但你还在两个测试中重新定义了 Student 。我的建议是使用已经定义的LoopBack应用程序和模型(通常在common/models/中)。然后测试的基本实现(我使用的)类似于下面的代码(使用mochachai)。请注意beforeEachafterEach来启动和停止服务器。

var assert = require('chai').assert,
    superagent = require('superagent'),
    app = require('../server/server');

describe('Person model', function() {
  var server;

  beforeEach(function(done) {
    server = app.listen(done);
  });

  afterEach(function(done) {
    server.close(done);
  });

  it('should log in and log out with live server', function(done) {
    superagent
      .post('http://localhost:3000/api/People/login')
      .send({ email: 'john@doe.com', password: 'foobar' })
      .set('Accept', 'application/json')
      .set('Content-Type', 'application/json')
      .end(function(err, loginRes) {
        if (err) { return done(err); }

          assert.equal(loginRes.status, 200);
          assert.ok(loginRes.body);
          assert.equal(loginRes.body.userId, 1);
        }
      });
  });
});

1
这就是示例代码了吗?如果你的LoopBack服务器中有模型,那么它们将通过server.js文件传递!尝试查看文档网站以了解如何定义模型。 - Jordan Kasper
我引用了 Student.updateOrCreate,这意味着需要引用 Student。因此,在测试中不需要声明 Student 吗?类似于 var Student = 什么的? - Dakotah North
如果“Student”是您的应用程序的一部分,那么您不应该在测试中定义它,而应该在应用程序中定义。我不确定为什么您要在测试中定义模型...您的模型是LoopBack应用程序的一部分! - Jordan Kasper
是的...完全同意。因为Student是通过JSON定义的,所以我如何访问Loopback的Student模型? - Dakotah North
我认为即使没有出错,也需要调用done函数。 - Rashi Abramson
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接