Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在fetch api中测试网络错误?_Javascript_Sinon_Chai - Fatal编程技术网

Javascript 如何在fetch api中测试网络错误?

Javascript 如何在fetch api中测试网络错误?,javascript,sinon,chai,Javascript,Sinon,Chai,我已经成功地在一个简单的应用程序上测试了已解决的承诺,我一直在学习ES6,但在测试可能存在网络错误的情况时遇到了问题 我编写了这个测试用例: import {Weather} from '../js/weather'; import chai from 'chai'; import sinon from 'sinon'; import * as chaiAsPromised from 'chai-as-promised'; chai.use(chaiAsPromised); let ass

我已经成功地在一个简单的应用程序上测试了已解决的承诺,我一直在学习ES6,但在测试可能存在网络错误的情况时遇到了问题

我编写了这个测试用例:

import {Weather} from '../js/weather';

import chai from 'chai';
import sinon from 'sinon';
import * as chaiAsPromised from 'chai-as-promised';

chai.use(chaiAsPromised);

let assert = chai.assert;
let should = chai.should;

describe('weatherbot-1', function () {
    beforeEach(function () {
        sinon.stub(window, 'fetch');

        let data = '{"cod": "400", "message": "Nothing to geocode"}';
        let res = new window.Response(data, {
            ok: false,
            status: 400,
            headers: {
                'Content-type': 'application/json'
            }
        });

        window.fetch.returns(Promise.reject(res));
    });

    afterEach(function () {
       window.fetch.restore();
    });

    it('should ensure that promise is rejected', function () {
        let weather = new Weather(0, 0);

        return assert.isRejected(weather.getWeather(), 'Rejected');
    });
});
所讨论的方法是:

getWeather() {
        let headers = new Headers();

        let init = {
            method: 'GET',
            headers: headers,
            cache: 'default'
        };

        let url = 'http://localhost:8080/weather?lat=' + '' + '&lon=' + this.longitude;

        return fetch(url, init).then(function (response) {
            return response.json();
        }).catch((error) => {
            return error;
        });
}
为了测试承诺,我使用
chai作为承诺
&
chai
mocha
&
sinon
来存根
获取
api

无论何时运行测试,都会出现以下错误:

AssertionError: expected promise to be rejected with an error including 'Rejected' but it was fulfilled with { type: 'default',
      url: '',
      redirected: false,
      status: 400,
      ok: false,
      statusText: 'OK',
      headers:
       { append: [Function: append],
         delete: [Function: delete],
         get: [Function: get],
         getAll: [Function: getAll],
         has: [Function: has],
         set: [Function: set],
         keys: [Function: keys],
         values: [Function: values],
         entries: [Function: entries],
         forEach: [Function: forEach] },
      body: {},
      bodyUsed: false,
      clone: [Function: clone],
      arrayBuffer: [Function: arrayBuffer],
      blob: [Function: blob],
      json: [Function: json],
      text: [Function: text] }

从外观上看,
Promise.reject()
可能无法正常工作。有没有其他方法可以测试网络错误

问题在于
getWeather
,而不是测试:

return fetch(url, init)
  .then(function (response) {
    return response.json();
  })
  .catch((error) => {
    return error;
  })
Promise#catch
返回已解决的承诺,因为它的任务是处理错误。应用程序的其余部分应该能够在捕获到拒绝后运行,就像使用
try/catch
一样

如果您希望拒绝到达测试,您的代码不应捕获拒绝:

return fetch(url, init)
  .then(function (response) {
    return response.json();
  })
一般来说,您应该只捕获可以正确处理错误的
catch
。在本例中,您可能希望在可以显示错误消息的视图中处理拒绝

此外,您的代码对无效情况进行建模
fetch
返回所有有效HTTP响应(包括非200状态)的已解析承诺

当它根本无法建立连接时,它会拒绝,例如
fetch(“http://sdfdsfsd)
。在这种情况下,它会使用
错误
对象进行拒绝


要正确测试
fetch
拒绝,您应该模拟此条件,并让存根返回
Promise.reject(新错误(“消息”)

函数中的catch子句返回一个新的、已实现的承诺。基本上,catch剥夺了你测试拒绝的能力。您可以做的是,对拒绝处理程序使用间谍,然后对其进行测试。

谢谢您的回答,我删除了
捕获
,但我得到了一个新错误:
TypeError:Cannot read Object.compatibleMessage(test/rejectedPromise.js:825:254)的undefined属性'indexOf'在test/rejectedPromise.js:8036:1432 at
中,这听起来像是
assert.isRejected
中的错误。我希望它假定拒绝值是一个带有字符串
message
属性的
错误。如果在拒绝中添加
消息
,错误是否会消失?我知道这不会是一个有代表性的
fetch
拒绝,但它有助于诊断问题。事实上,再多读一读你的代码-这个承诺不会被
fetch
拒绝
fetch
返回有效HTTP响应的已解析承诺,其中包含非200个错误代码。@DeliciousMuffin取决于您要测试的内容。您可以有单独的“使用400解析”和“使用TypeError拒绝”测试。我已经更新了答案。我明白了,谢谢你这么详细的回答!我确实学到了一些关于承诺的东西。顺便问一下,是否有一个全面的来源,我可以了解更多关于承诺?