QUnit, Sinon.js — Как убедиться, что сообщение Post to Fake Server имеет правильное тело запроса?

У меня есть функция JavaScript, которая отправляет сообщение в удаленный API, для которого я собираюсь написать модульный тест. Метод, который я хочу проверить, таков:

var functionToTest = function(callback, fail) {
    $.ajax({
        url: "/myapi/",
        type: "POST",
        data: { one: 'one', two: 'two' },
        accept: "application/json",
        contentType: "application/json"
    }).done(function(x) {
        log = generateLogMessage('Success');
        callback(log);
    }).fail(function(x, s, e) {
        log = generateLogMessage('Fail');
        fail(log);
    });
}

У меня есть модульный тест (в QUnit с использованием Sinon.js), который проверяет правильность обратного вызова при успешном выполнении запроса:

QUnit.test('Test that the thing works', function () {

    var server = this.sandbox.useFakeServer();

    server.respondWith(
        'POST',
        '/myapi/',
        [
            200,
            {'Content-Type': 'application/json'},
            '{"Success":true}'
        ]
    );

    var callback = this.spy();
    functionToTest(callback, callback);
    server.respond();

    QUnit.ok(callback.calledWith(generateLogMessage('Success')));
});

Этот тест работает, но он успешно возвращается независимо от тела запроса. Я хочу, чтобы поддельный сервер отвечал только в том случае, если тело запроса { one: 'one', two: 'two' }


person BeardedCoder    schedule 24.01.2014    source источник


Ответы (2)


Я собирался предложить вам использовать отфильтрованные запросы. Однако это невозможно с текущей реализацией sinon.

выдержка из документации:

Добавьте фильтр, который будет решать, подделывать запрос или нет. Фильтр будет вызываться при вызове xhr.open с точно такими же аргументами (метод, URL, асинхронность, имя пользователя, пароль). Если фильтр возвращает истину, запрос не будет подделан.

У вас нет возможности фильтровать данные.

РЕДАКТИРОВАТЬ: Если я правильно понимаю проблему, вы можете сделать что-то вроде этого:

functionToTest(...);
var request = server.requests[0];
var data = JSON.parse(request.requestBody);
if (data.one == 'one' && data.two == 'two') {
  request.respond(200, jsonHeaders, JSON.stringify(specialResponse));
}
else {
  request.respond(200, jsonHeaders, JSON.stringify(otherResponse));
}

Я знаю, что этот код даст правильный результат, который вы хотите, но прямо сейчас нет способа программно добиться этого с помощью sinon.

person fearphage    schedule 12.02.2014
comment
Спасибо, я думаю, что я буду продолжать делать то, что я делаю тогда. - person BeardedCoder; 03.03.2014

Почти два года спустя, но все еще актуально:

Этого можно добиться, передав функцию вместо массива в качестве третьего параметра функции server.respondWith. Функция принимает один аргумент 'запрос', по которому можно вызвать request.respond(statusCode, headers, body);

Вам все равно придется извлекать значения из request.requestBody, но, по крайней мере, это выполнимо.

QUnit.test('Test that the thing works', function () {

    var server = this.sandbox.useFakeServer();

    server.respondWith(
        'POST',
        '/myapi/',
        function (request) {
            console.log(request.requestBody); // <- assert here :-)
            request.respond(200, {'Content-Type': 'application/json'}, '{"Success":true}');
        }
    );

    var callback = this.spy();
    functionToTest(callback, callback);
    server.respond();

    QUnit.ok(callback.calledWith(generateLogMessage('Success')));
});
person sgtdck    schedule 08.12.2015
comment
Код для xhr.respond: github.com /sinonjs/sinon/blob/ - person Luqmaan; 26.02.2016
comment
Это должен быть настоящий ответ сейчас - person jesantana; 29.06.2016