问题
I've tried and tried to get this to work. The documentation is terse, at best:
resetExpectations(); - Resets all request expectations, but preserves all backend definitions. Typically, you would call resetExpectations during a multiple-phase test when you want to reuse the same instance of $httpBackend mock.
Every time my second request is called, my result always has the first result's data. Check out this fiddle http://jsfiddle.net/tbwn1gt0/2/ where I reset the expectations after the first flush, then set new expectations/result then flush again to yield the incorrect data.
// --- SPECS -------------------------
var url = '/path/to/resource';
var result = '';
describe('$httpBackend', function () {
it("expects GET different results in subsequent requests", inject(function ($http, $httpBackend) {
successCallback = function(data){
result = data;
}
// Create expectation
$httpBackend.expectGET(url).respond(200, 'mock data');
// Call http service
$http.get(url).success(successCallback);
// flush response
$httpBackend.flush();
console.log( result ); // logs 'mock data'
// Verify expectations
expect( result ).toContain('mock data'); // works as it should
// reset the expectations
$httpBackend.resetExpectations();
// set the fake data AGAIN
$httpBackend.expectGET(url).respond(200, 'doof the magic cragwagon');
// get the service AGAIN
$http.get(url).success(successCallback);
expect( result ).toContain('doof'); // does not work, result is original result
console.log( result ); // logs 'mock data'
}));
});
// --- Runner -------------------------
(function () {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function (spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function () {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
Other things I've tried include adding an afterEach with resetExpectations (putting each request in a new it statement). and a slew of other random attempts. If it try to change the expected url to something not expected, it errors as it should-- so I know the requests are getting handled through httpBackend at the very least.
Is this a defect or am I implementing it incorrectly?
回答1:
The .resetExpectations()
does work as you expected, but you just forgot to flush a http request for the second one.
// set the fake data AGAIN
$httpBackend.expectGET(url).respond(200, 'doof the magic cragwagon');
// get the service AGAIN
$http.get(url).success(successCallback);
$httpBackend.flush(); // flush the second http request here
expect( result ).toContain('doof'); // does not work, result is original result
console.log( result ); // logs 'mock data'
Example JSFiddle: http://jsfiddle.net/4aw0twjf/
PS. Actually, the $httpBackend.resetExpectations()
is not necessary for your test case.
回答2:
Your case doesn't require to reset expectations. You can modify behavior of expectation instead clear & create new one. "expectGET" (and other methods) returns requestHandler, e.g.:
// Create expectation
var expectationHandler = $httpBackend.expectGET(url).respond(200, 'mock data');
// Call http service, flush response, verify expectations
// Modify behavior
expectationHandler.respond(200, 'doof the magic cragwagon');
// Call http service ... AGAIN
回答3:
Since you have multiple calls I would use this at the end of each test to verify that all http calls are successful expect($httpBackend.flush).not.toThrow();
, which means that you don't have to invoke $httpBackend.flush();
for every http call.
Also, you it's nice to add an afterEach
block like this.
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectations();
});
来源:https://stackoverflow.com/questions/25370273/how-to-actually-reset-httpbackend-expectations