在 Express 代码的 Mocha 测试中编码 JSON POST 数据

Encoding JSON POST data in Mocha test of Express code

我的 Express 代码在从 Postman 调用时运行良好,但在从 Mocha 调用时运行不正常。这让我相信我的 Mocha 测试没有在 POST 请求的 header 中正确设置数据(我对无参数 GET 或 POST 没有问题,对带参数的 GET 也没有问题; 只有带参数的 POST).

这是简单的代码,虽然我不会专注于此,因为它来自 Postman:

const app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// Our unit tests send POST data in JSON format
app.use(express.json());


// Helper function - common code
function ResplyWithSentence(object, adjective)
{
  console.log('GET requestuest received: object = ' + object + '; adjective = ' + adjective);

  let sentence = softwareUnderTest.MakeAsentence(object, adjective);
  sentence = JSON.stringify(sentence);
  response.status(200);
  response.set('Content-Type', 'text/json');
  response.send( sentence );
}


// Handling POST request with parameters
app.post("/makeSentenceParamsPost", (request, response) => {
  const object    = request.body.object;
  const adjective = request.body.adjective;

  ResplyWithSentence(object, adjective);
})

这是 Postman 发送的内容:

POST /makeSentenceParamsPost HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 88dfc7cc-427e-3248-ba93-286083d4c18d

{
    "object": "cat",
    "adjective": "sleepy"
}

这是摩卡咖啡:

    it('should handle a POST request with parameters', async function(){
        var xhttp = new XMLHttpRequest();
        xhttp.open("POST", "http://localhost:3000/makeSentenceParamsPost", false);      // false === synchronous/blocking
        xhttp.setRequestHeader("Content-type", "application/json");

        const object = 'hubris';
        const adjective = 'pervasive';
        let   postParameters = {'object': object,
                                'adjective': adjective};

        xhttp.onreadystatechange = function(done) {
            while(this.readyState != 4) ;       // wait until "request finished and response is ready"

            assert.isObject(this);
            assert(this.status == 200);

            assert(JSON.parse(this.responseText)['sentence'] == `The ${object} is ${adjective}`);
            done();
    };

    postParameters = JSON.stringify(postParameters);
    xhttp.send(postParameters);
});

收到的回复是The undefined is undefined.

谁能告诉我我做错了什么?或者甚至如何调试它?

使用现代JavaScript!

我建议研究一下 fetch。它是 ES5 的等价物并使用 Promises。它更具可读性和易于定制。

const fetch = require("node-fetch");

const first = 'hubris'; // can't use words like object, these are reserved.
const second = 'pervasive';
let postParameters = {'first': first,
                                'second': second};
const url = "http://example.com";
fetch(url, {
    method : "POST",
    body: postParameters,
    // -- or --
    // body : JSON.stringify({
        // user : document.getElementById('user').value,
        // ...
    // })
}).then(
    response => response.text() // .json(), etc.
    
        assert.isObject(this);
        assert(this.status == 200);
        assert(JSON.parse(this.responseText)['sentence'] == `The ${object} is ${adjective}`);
        done();
);

类型上的大写 T 解决了问题:

xhttp.setRequestHeader("Content-Type", "application/json");