web-dev-qa-db-ja.com

Express Middlewareを単体テストする正しい方法

私のサーバーにヒットするすべてのPOSTリクエストで有効なContent-Typeヘッダーをチェックするように設定されているExpressミドルウェアがあり、このミドルウェアのコードは以下のとおりです。

import * as STRINGS from "../Common/strings";

function ContentTypeValidator(req, res, next) {
    let contentHeader = req.get("content-type");
    if(!contentHeader) {
        res.status(400).send(STRINGS.ERROR_CONTENT_TYPE_MISSING);
    } else {
        if(contentHeader.toLowerCase() !== "application/json") {
            res.status(415).send(STRINGS.ERROR_CONTENT_TYPE_UNSUPPORTED);
        } else {
            next();
        }
    }
}

export default ContentTypeValidator;

TDDにmochachaiおよびnode-mocks-httpを使用しており、next()が呼び出されないため、res.send()がこのリクエストの終わりです。

it("Should return 200 for valid Content-Type header", (done) => {
    req = nodeMocks.createRequest({
        headers: {
            "Content-Type": "application/json"
        }
    });
    ContentTypeValidator(req, res, (err) => {
        res.statusCode.should.equal(200);
        expect(err).to.be.undefined;
        done();
    });
});

it("Should return 400 if Content-Type header is missing", (done) => {
    ContentTypeValidator(req, res, () => {});
    res.statusCode.should.equal(400);
    res._getData().should.equal("Content-Type header missing");
    done();
});

上記の最初のテストでは、これがパスすることを期待しているので、next()関数として機能する関数を渡し、このテストはパスします。 2番目のテストでは、これが失敗することを期待しています。そのため、関数を渡すと、コールバック関数が呼び出されないため、テストが2000ミリ秒を超えたとmocahが不平を言います。これは、res.send()がこのインスタンス。

このようなExpressミドルウェアの単体テストに関して、2番目のテストの記述方法は正しいですか、またはこれを行うためのより良い/より賢明な方法はありますか?

編集:だから明確にするために、私は次のコールバックが呼び出されないときにミドルウェアをテストすることに焦点を当てています、私が明らかに重複している質問は、sinonを使用して次が呼び出されるかどうかを確認することです。コールバック関数が呼び出されないときにユニットテストを行う方法を探しています。

9
Jak Hammond

この答えをチェックしてください

https://stackoverflow.com/a/34517121/4996928

var expect = require('chai').expect;
var sinon  = require('sinon');

var middleware = function logMatchingUrls(pattern) {
    return function (req, res, next) {
        if (pattern.test(req.url)) {
            console.log('request url', req.url);
            req.didSomething = true;
        }
        next();
    }
}

describe('my middleware', function() {

  describe('request handler creation', function() {
    var mw;

    beforeEach(function() {
      mw = middleware(/./);
    });

    it('should return a function()', function() {
      expect(mw).to.be.a.Function;
    });

    it('should accept three arguments', function() {
      expect(mw.length).to.equal(3);
    });
  });

  describe('request handler calling', function() {
    it('should call next() once', function() {
      var mw      = middleware(/./);
      var nextSpy = sinon.spy();

      mw({}, {}, nextSpy);
      expect(nextSpy.calledOnce).to.be.true;
    });
  });

  describe('pattern testing', function() {
    ...
  });

});
9
Med Lazhari