2015-04-22 91 views
2

我试图测试一个间谍将被称为承诺的.then块,但块done似乎并未执行在所有。摩卡 - 测试承诺,`完成`永远不会被调用在承诺

我越来越timeout of 2000ms exceeded.

这里是我测试(异步):

/** 
* Passed down to the LoginForm component to 
* handle form submission. 
*/ 
_submitHandler(data) { 
    return function(evt) { 
    evt.preventDefault && evt.preventDefault(); 
    evt.stopPropagation && evt.stopPropagation(); 

    return request('post', 'auth', data) 
     .then((res) => { 
     AuthActions.login(); 
     return res; 
     }) 
    } 
} 

这里是我的测试:

describe('when it succeeds',() => { 
    it('should login', (done) => { 
    sinon.spy(AuthActions, 'login'); 

    Instance._submitHandler({})({}) 
     .then((res) => { 
     console.log('Called!!!'); 
     expect(AuthActions.login.called).to.equal(true); 
     AuthActions.login.restore(); 
     done(); 
     }, done); 
    }); 
}); 

我使用噶运行我的测试;柴和诗乃。

+0

你会得到什么失败的消息? – Bergi

回答

1

几小时后我终于解决了这个问题。看起来then块没有被调用,因为由于xhr而引发异常。

让我详细说明。我用兴农FakeXMLHttpRequest,就像这样:

var requests, xhr; 
beforeEach(() => { 
    requests = []; 
    xhr = sinon.useFakeXMLHttpRequest(); 
    xhr.onCreate = (req) => { 
    req.setResponseHeaders({ /* */ }); 
    requests.push(req); 
    } 
}); 

通过将一个console.logcatch块,我发现我越来越错误是INVALID_STATE_ERR EXCEPTION 0。这让我得出结论,xhr一直是问题。

然后我发现了约sinonfakeServer,并用它来代替(但我不认为这实际上是解决这个问题的方法)。不是真的有关,但我还用​​这里是因为从写无数的.restore为存根救了我,等

describe('when it succeeds',() => { 
    var sandbox, server, Instance; 
    beforeEach(() => { 
    sandbox = sinon.sandbox.create(); 
    sandbox.useFakeServer(); 
    server = sandbox.server; 
    server.respondWith([200, { "Content-Type": "application/json" }, JSON.stringify({ data: { token: '' }})]); 
    sandbox.spy(AuthActions, 'login'); 
    Instance = TestUtils.renderIntoDocument(<Component />); 
    }); 
    afterEach(() => { 
    sandbox.restore(); 
    }); 
    it('should login', (done) => { 
    Instance._submitHandler({})({}) 
     .then(() => { 
     expect(AuthActions.login.called).to.equal(true); 
     done(); 
     }, done); 

    setTimeout(() => { 
     server.respond(); 
    }, 0); 
    }); 
}); 
2

我也有这个问题,原因是想给XHR回应打开连接之前, ,例如

此代码将抛出INVALID_STATE_ERR - 0FakeXMLHttpRequest.setResponseHeaders

describe("get", function() { 

    beforeEach(function() { 
    this.xhr = sinon.useFakeXMLHttpRequest(); 
    this.xhr.onCreate = function (request) { 
     request.respond(200, null, ""); 
    }; 
    }); 

    afterEach(function() { 
    this.xhr.restore(); 
    }); 

    it("should make a request", function() { 
    myObject.get("testurl"); 
    }); 

}); 

此代码:

describe("get", function() { 

    beforeEach(function() { 
    this.xhr = sinon.useFakeXMLHttpRequest(); 
    this.requests = []; 
    this.xhr.onCreate = function (request) { 
     this.requests.push(request); 
    }; 
    }); 

    afterEach(function() { 
    this.xhr.restore(); 
    }); 

    it("should make a request", function() { 
    myObject.get("testurl"); 
    this.requests[0].respond(200, null, ""); 
    }); 

}); 

阅读该文档,它本身确实显示出推到一个请求阵列相同的技术,我有下意识地,不准确地得出了这样的印象,尽管它的名字是onCreate,更像是“应要求”。

myObject.get = function (url) { 
    var http = new XMLHttpRequest(); 
    // the XHR instance exists 
    // readyState is 0 
    // onCreate runs now 
    http.open("GET", url); 
    http.send(); 
    // readyState is 1 
    // can call setResponseHeaders and respond 
} 

的结果是,你必须把你的响应代码调用运行XMLHttpRequestsend的方法,如后:

myObject.get("testurl"); 
this.requests[0].respond(200, null, ""); 

我用的是respond方法,但相同的是对于setResponseHeadersrespond调用setResponseHeaders)为真 - 在您的测试中,它被称为太早。