代码之家  ›  专栏  ›  技术社区  ›  Buddy Lindsey

在测试中似乎根本并没有调用Sinon存根,即使它在以前的测试中工作正常

  •  -1
  • Buddy Lindsey  · 技术社区  · 7 年前

    我正试图用sinon测试express路由器的功能。我的测试如下,第一次测试通过得很好,没有问题。然而,第二个没有通过。我不明白为什么。

    如果我向路由发送http请求,它将按预期工作。

    渔获量引起了一些问题。下面是我能够将其缩减为的代码和错误

    书js公司

    import express from 'express';
    import models from '../db/models';
    const router = express.Router();
    
    var indexPost = async (req, res, next) => {
      try {
        let savedBook = await models.Book.create({
          title: req.body.title || null,
          isbn: req.body.isbn || null,
          author: req.body.author || null
        });
        res.status(201).json({ book: savedBook.id });
      } catch (err) {
        res.status(400).send('');
      }
    };
    router.post('/', indexPost);
    
    export default router;
    export { indexPost };
    

    书测验js公司

    import { indexPost } from '../../../src/routes/books';
    import models from '../../../src/db/models';
    import sinon from 'sinon';
    import { expect } from 'chai';
    import sinonTestFactory from 'sinon-test';
    
    const sinonTest = sinonTestFactory(sinon);
    
    describe('Books router', () => {
      describe('indexPost', () => {
        it('should save the book to the database', sinonTest(async function () {
          let req = {
            body: {
              title: 'Book Title',
              isbn: '123asera23',
              author: 123
            }
          };
    
          let res = {
            status: status => {},
            json: json => {}
          };
    
          this.stub(res, 'status').returns(res);
          this.stub(res, 'json').returns(res);
    
          indexPost(req, res);
    
          let book = await models.Key.findById(1);
    
          expect(book.title).to.equal('Book Title');
          expect(book.isbn).to.equal('123asera23');
          expect(book.author).to.equal(123);
    
          sinon.assert.calledWith(res.status, 201);
          sinon.assert.calledWith(res.json, { book: 1 });
        }));
    
        it('should throw an error if data is not all there', sinonTest(async function () {
          let req = {
            body: {
              title: 'Book Title',
              author: 123
            }
          };
    
          let res = {
            status: status => {},
            send: send => {}
          };
    
          this.stub(res, 'status').returns(res);
          this.stub(res, 'send').returns(res);
    
          indexPost(req, res);
    
          sinon.assert.calledWith(res.status, 400);
          sinon.assert.calledWith(res.send, '');
        }));
      });
    });
    

    错误

    1) Books router
        indexPost
            should throw an error if data is not all there:
                AssertError: expected status to be called with arguments
                at Object.fail (/var/app/node_modules/sinon/lib/sinon/assert.js:96:21)
                at failAssertion (/var/app/node_modules/sinon/lib/sinon/assert.js:55:16)
                at Object.assert.(anonymous function) [as calledWith] (/var/app/node_modules/sinon/lib/sinon/assert.js:80:13)
                at Context.<anonymous> (tests/src/routes/books.test.js:58:20)
                at Generator.next (<anonymous>)
                at step (tests/src/routes/books.test.js:21:191)
                at tests/src/routes/keys.test.js:21:437
                at new Promise (<anonymous>)
                at Context.<anonymous> (tests/src/routes/books.test.js:21:99)
                at callSandboxedFn (/var/app/node_modules/sinon-test/lib/test.js:94:25)
                at Context.sinonSandboxedTest (/var/app/node_modules/sinon-test/lib/test.js:114:24)
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Buddy Lindsey    7 年前

    因为没有人看到这一点来意识到这并不是一个简单的不平等的断言,所以我将发布我最终得出的真实答案。

    基本上,我的测试方法是错误的。我对javascript中的非异步代码只做了一半的解释。

    我需要做的是回报一个对摩卡的承诺 it 作用为了做到这一点,我的控制器还需要回报一个承诺。在做数据库工作的情况下,我可以返回数据库调用承诺。

    一旦承诺召唤 resolve reject . 然后,您可以进行断言,看看测试是否有效。

    他们的关键是,你必须将承诺从控制者的最底层一直链接到 摩卡咖啡的功能。

    下面是解决此问题的代码。

    import express from 'express';
    import models from '../db/models';
    const router = express.Router();
    
    var indexPost = (req, res, next) => {
      return models.Book.create({
        title: req.body.title || null,
        isbn: req.body.isbn || null,
        author: req.body.author || null
      }).then(savedBook => {
        res.status(201).json({ book: savedBook.id });
      }).catch(err => {
        res.status(400).send('');
      });
    };
    router.post('/', indexPost);
    
    export default router;
    export { indexPost };
    
    import { indexPost } from '../../../src/routes/books';
    import models from '../../../src/db/models';
    import sinon from 'sinon';
    import { expect } from 'chai';
    
    describe('Books router', () => {
      describe('indexPost', () => {
        it('should save the book to the database', async () => {
          let req = {
            body: {
              title: 'Book Title',
              isbn: '123asera23',
              author: 123
            }
          };
    
          const jsonStub = sinon.stub()
          const res = { status: status => ({ json: jsonStub, send: err => err }) }
          const statusSpy = sinon.spy(res, 'status')
    
          return indexPost(req, res).then(() => {
            let book = await models.Key.findById(1);
    
            expect(book.title).to.equal('Book Title');
            expect(book.isbn).to.equal('123asera23');
            expect(book.author).to.equal(123);
    
            sinon.assert.calledWith(res.status, 201);
            sinon.assert.calledWith(res.json, { book: 1 });
          })
        }));
    
        it('should throw an error if data is not all there', () => {
          let req = {
            body: {
              title: 'Book Title',
              author: 123
            }
          };
    
          const sendStub = sinon.stub()
          const res = { status: status => ({ json: err => err, send: sendStub }) }
          const statusSpy = sinon.spy(res, 'status')
    
          indexPost(req, res).then(() => {
            sinon.assert.calledWith(res.status, 400);
            sinon.assert.calledWith(res.send, '');
          });
        }));
      });
    });
    

    我的响应对象也有一些奇怪之处,上面的代码也解决了这个问题。