#javascript #node.js #ecmascript-6 #jestjs
#javascript #node.js #ecmascript-6 #jestjs
Вопрос:
Ниже можно опробовать вживую на https://repl.it/@SandraSchlichti/jest-playground-3#getStatusCode.test.js
Первоначально приведенный ниже тест имел status: 200
, но я попытался изменить его 301
, чтобы посмотреть, понял ли я, как это работает.
describe('when the server returns 200', () => {
let resu<
//??? The desired purpose of this test is to have a mis-match between expected and
//??? returned status code so getStatusCode() returns 0.
//??? Trying to figure out how this test works.
//??? Here I have changed status to 301 and expected the test to fail, but it didn't
//??? From my understanding mockResponseData contains status 301, and status below
//??? should override that? But that doesn't seam to be the case for some reason.
beforeAll(async () => {
axios.get.mockResolvedValue({
status: 301,
data: mockResponseData
});
result = await getStatusCode();
});
it('should return 0', () => {
expect(result).toEqual(0)
})
});
Вопрос
Я ожидал, что тест завершится неудачей, когда я изменил его на status: 301
, как getStatusCode()
должно вернуться 1
, когда коды состояния совпадут.
- Почему тест не завершается неудачей?
- Можно ли изменить тест, чтобы сделать его более понятным, что ожидаемые и возвращенные коды состояния не совпадают?
- По какой-то причине порядок и не имеет значения.
status
data
Почему это? Разве неstatus: 301
предполагается переопределитьstatus
внутреннююmockResponseData
часть? - Если я внутри
mockResponseData.json
изменяюstatus
на9999
, то все тесты не затрагиваются. У меня такое ощущение, что содержимое вmockResponseData.json
не используется вообще?
Это файлы, необходимые для локальной проверки:
mockedResponseData.json
{
"status": 301,
"statusText": "Moved Permanently",
"headers": {
"location": "https: //www.google.com/",
"content-type": "text/html; charset=UTF-8",
"date": "Thu, 12 Nov 2020 10: 09: 41 GMT",
"expires": "Sat, 12 Dec 2020 10: 09: 41 GMT",
"cache-control": "public, max-age=2592000",
"server": "gws",
"content-length": "220",
"x-xss-protection": "0",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "h3-Q050=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"",
"connection": "close"
}
}
getStatusCode.test.js
const axios = require('axios');
const getStatusCode = require('./getStatusCode');
const mockResponseData = require('./mockResponseData.json');
jest.mock("axios");
describe("getStatusCode ", () => {
describe('when the server returns status code matching options.statusCode', () => {
let resu<
beforeAll(async () => {
axios.get.mockResolvedValue({
status: 200,
data: mockResponseData
})
result = await getStatusCode({
statusCode: 200
})
});
it('should return 1', () => {
expect(result).toEqual(1)
})
});
describe('when the server returns 200', () => {
let resu<
//??? The desired purpose of this test is to have a mis-match between expected and returned status code,
//??? getStatusCode() returns 0.
//??? Trying to figure out how this test works.
//??? Here I have changed status to 301 and expected the test to fail, but it didn't
//??? From my understanding mockResponseData contains status 301, and status below should override that?
//??? But that doesn't seam to be the case for some reason.
beforeAll(async () => {
axios.get.mockResolvedValue({
status: 301,
data: mockResponseData
});
result = await getStatusCode();
});
it('should return 0', () => {
expect(result).toEqual(0)
})
});
describe("when expected and returned status code doesn't match", () => {
let resu<
beforeAll(async () => {
// mockRejected value returns rejected promise
// which will be handled by the try/catch
axios.get.mockRejectedValue({
status: 200,
data: mockResponseData
})
result = await getStatusCode();
})
it('should return -1', () => {
expect(result).toEqual(-1)
})
});
});
getStatusCode.js
const axios = require('axios');
const qs = require('qs');
module.exports = async (options) => {
options = options || {};
options.url = options.url || {};
options.statusCode = options.statusCode || 0;
options.timeout = options.timeout || 1000;
options.maxRedirects = options.maxRedirects || 0;
try {
const response = await axios.get(options.url, {
timeout: options.timeout,
maxRedirects: options.maxRedirects,
// make all http status codes a success
validateStatus: function (status) {
return true;
}
});
return (response.status === options.statusCode) ? 1 : 0;
} catch (error) {
return -1;
}
};
Комментарии:
1. Теперь добавлен @Andreas.
2. В тесте, на который вы указали, статус равен 301, а StatusCode по умолчанию равен 0, 301 != 0, поэтому он возвращает 0. Пожалуйста, уточните, каковы именно ваши ожидания и почему.
3. Почему по умолчанию он равен нулю, когда я предоставил входной аргумент
status: 301
?4. Из
options.statusCode = options.statusCode || 0
-за . Вы указали{ statusCode: 200 }
в одном тесте, но не в другом, отсюда и разница.5. Из того, что я вижу, единственный способ, которым связаны status и StatusCode, заключается в том, что они сравниваются друг с другом в
return (response.status === options.statusCode) ? 1 : 0
. ТакимgetStatusCode()
образом, без опции StatusCode всегда будет возвращать 0, если статус ответа не равен 0 (статус 0 зарезервирован для ошибок запроса на стороне клиента, но я не помню, следует ли Axios соглашению).
Ответ №1:
Когда вы не передаете никаких аргументов, по result = await getStatusCode();
умолчанию он будет равен нулю. Если вы этого не хотите, тогда сделайте
describe('when the server returns 200', () => {
let resu<
beforeAll(async () => {
axios.get.mockResolvedValue({
status: 301,
data: mockResponseData
});
result = await getStatusCode({
statusCode: 200 // <-----------
});
});
it('should return 0', () => {
expect(result).toEqual(0)
})
});