Почему этот тест шутки не завершается неудачей?

#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 , когда коды состояния совпадут.

  1. Почему тест не завершается неудачей?
  2. Можно ли изменить тест, чтобы сделать его более понятным, что ожидаемые и возвращенные коды состояния не совпадают?
  3. По какой-то причине порядок и не имеет значения. status data Почему это? Разве не status: 301 предполагается переопределить status внутреннюю mockResponseData часть?
  4. Если я внутри 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)
    })
  });