mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-09 09:00:34 +08:00
feat(mocks.$httpBackend): add $httpBackend mock
$httpBackend mock allows: - expecting (asserting) requests - stubbing (responding without asserting) Add empty $httpBackend service (currently just wrapper for $browser.xhr)
This commit is contained in:
397
test/angular-mocksSpec.js
vendored
397
test/angular-mocksSpec.js
vendored
@@ -342,4 +342,401 @@ describe('mocks', function() {
|
||||
expect(count).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('$httpBackend', function() {
|
||||
var hb, callback;
|
||||
|
||||
beforeEach(inject(function($httpBackend) {
|
||||
callback = jasmine.createSpy('callback');
|
||||
hb = $httpBackend;
|
||||
}));
|
||||
|
||||
|
||||
it('should respond with first matched definition', function() {
|
||||
hb.when('GET', '/url1').then(200, 'content', {});
|
||||
hb.when('GET', '/url1').then(201, 'another', {});
|
||||
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(200);
|
||||
expect(response).toBe('content');
|
||||
});
|
||||
|
||||
hb('GET', '/url1', null, callback);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
hb.flush();
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
|
||||
it('should throw error when unexpected request', function() {
|
||||
hb.when('GET', '/url1').then(200, 'content');
|
||||
expect(function() {
|
||||
hb('GET', '/xxx');
|
||||
}).toThrow('Unexpected request: GET /xxx');
|
||||
});
|
||||
|
||||
|
||||
it('should match headers if specified', function() {
|
||||
hb.when('GET', '/url', null, {'X': 'val1'}).then(201, 'content1');
|
||||
hb.when('GET', '/url', null, {'X': 'val2'}).then(202, 'content2');
|
||||
hb.when('GET', '/url').then(203, 'content3');
|
||||
|
||||
hb('GET', '/url', null, function(status, response) {
|
||||
expect(status).toBe(203);
|
||||
expect(response).toBe('content3');
|
||||
});
|
||||
|
||||
hb('GET', '/url', null, function(status, response) {
|
||||
expect(status).toBe(201);
|
||||
expect(response).toBe('content1');
|
||||
}, {'X': 'val1'});
|
||||
|
||||
hb('GET', '/url', null, function(status, response) {
|
||||
expect(status).toBe(202);
|
||||
expect(response).toBe('content2');
|
||||
}, {'X': 'val2'});
|
||||
|
||||
hb.flush();
|
||||
});
|
||||
|
||||
|
||||
it('should match data if specified', function() {
|
||||
hb.when('GET', '/a/b', '{a: true}').then(201, 'content1');
|
||||
hb.when('GET', '/a/b').then(202, 'content2');
|
||||
|
||||
hb('GET', '/a/b', '{a: true}', function(status, response) {
|
||||
expect(status).toBe(201);
|
||||
expect(response).toBe('content1');
|
||||
});
|
||||
|
||||
hb('GET', '/a/b', null, function(status, response) {
|
||||
expect(status).toBe(202);
|
||||
expect(response).toBe('content2');
|
||||
});
|
||||
|
||||
hb.flush();
|
||||
});
|
||||
|
||||
|
||||
it('should match only method', function() {
|
||||
hb.when('GET').then(202, 'c');
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(202);
|
||||
expect(response).toBe('c');
|
||||
});
|
||||
|
||||
hb('GET', '/some', null, callback, {});
|
||||
hb('GET', '/another', null, callback, {'X-Fake': 'Header'});
|
||||
hb('GET', '/third', 'some-data', callback, {});
|
||||
hb.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
it('should expose given headers', function() {
|
||||
hb.when('GET', '/u1').then(200, null, {'X-Fake': 'Header', 'Content-Type': 'application/json'});
|
||||
var xhr = hb('GET', '/u1', null, noop, {});
|
||||
hb.flush();
|
||||
expect(xhr.getResponseHeader('X-Fake')).toBe('Header');
|
||||
expect(xhr.getAllResponseHeaders()).toBe('X-Fake: Header\nContent-Type: application/json');
|
||||
});
|
||||
|
||||
|
||||
it('should preserve the order of requests', function() {
|
||||
hb.when('GET', '/url1').then(200, 'first');
|
||||
hb.when('GET', '/url2').then(201, 'second');
|
||||
|
||||
hb('GET', '/url2', null, callback);
|
||||
hb('GET', '/url1', null, callback);
|
||||
|
||||
hb.flush();
|
||||
|
||||
expect(callback.callCount).toBe(2);
|
||||
expect(callback.argsForCall[0]).toEqual([201, 'second']);
|
||||
expect(callback.argsForCall[1]).toEqual([200, 'first']);
|
||||
});
|
||||
|
||||
|
||||
it('then() should take function', function() {
|
||||
hb.when('GET', '/some').then(function(m, u, d, h) {
|
||||
return [301, m + u + ';' + d + ';a=' + h.a, {'Connection': 'keep-alive'}];
|
||||
});
|
||||
|
||||
var xhr = hb('GET', '/some', 'data', callback, {a: 'b'});
|
||||
hb.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
expect(callback.mostRecentCall.args[0]).toBe(301);
|
||||
expect(callback.mostRecentCall.args[1]).toBe('GET/some;data;a=b');
|
||||
expect(xhr.getResponseHeader('Connection')).toBe('keep-alive');
|
||||
});
|
||||
|
||||
|
||||
it('expect() should require specified order', function() {
|
||||
hb.expect('GET', '/url1').respond(200, '');
|
||||
hb.expect('GET', '/url2').respond(200, '');
|
||||
|
||||
expect(function() {
|
||||
hb('GET', '/url2', null, noop, {});
|
||||
}).toThrow('Unexpected request: GET /url2');
|
||||
});
|
||||
|
||||
|
||||
it('expect() should have precendence over when()', function() {
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(300);
|
||||
expect(response).toBe('expect');
|
||||
});
|
||||
|
||||
hb.when('GET', '/url').then(200, 'when');
|
||||
hb.expect('GET', '/url').respond(300, 'expect');
|
||||
|
||||
hb('GET', '/url', null, callback, {});
|
||||
hb.flush();
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
|
||||
it ('should throw exception when only headers differes from expectation', function() {
|
||||
hb.when('GET').then(200, '', {});
|
||||
hb.expect('GET', '/match', undefined, {'Content-Type': 'application/json'});
|
||||
|
||||
expect(function() {
|
||||
hb('GET', '/match', null, noop, {});
|
||||
}).toThrow('Expected GET /match with different headers');
|
||||
});
|
||||
|
||||
|
||||
it ('should throw exception when only data differes from expectation', function() {
|
||||
hb.when('GET').then(200, '', {});
|
||||
hb.expect('GET', '/match', 'some-data');
|
||||
|
||||
expect(function() {
|
||||
hb('GET', '/match', 'different', noop, {});
|
||||
}).toThrow('Expected GET /match with different data');
|
||||
});
|
||||
|
||||
|
||||
it('expect() should without respond() and use then()', function() {
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(201);
|
||||
expect(response).toBe('data');
|
||||
});
|
||||
|
||||
hb.when('GET', '/some').then(201, 'data');
|
||||
hb.expect('GET', '/some');
|
||||
hb('GET', '/some', null, callback);
|
||||
hb.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalled();
|
||||
expect(function() { hb.verifyExpectations(); }).not.toThrow();
|
||||
});
|
||||
|
||||
|
||||
it('flush() should not flush requests fired during callbacks', function() {
|
||||
// regression
|
||||
hb.when('GET').then(200, '');
|
||||
hb('GET', '/some', null, function() {
|
||||
hb('GET', '/other', null, callback);
|
||||
});
|
||||
|
||||
hb.flush();
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
it('flush() should flush given number of pending requests', function() {
|
||||
hb.when('GET').then(200, '');
|
||||
hb('GET', '/some', null, callback);
|
||||
hb('GET', '/some', null, callback);
|
||||
hb('GET', '/some', null, callback);
|
||||
|
||||
hb.flush(2);
|
||||
expect(callback).toHaveBeenCalled();
|
||||
expect(callback.callCount).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
it('flush() should throw exception when flushing more requests than pending', function() {
|
||||
hb.when('GET').then(200, '');
|
||||
hb('GET', '/url', null, callback);
|
||||
|
||||
expect(function() {hb.flush(2);}).toThrow('No more pending requests');
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
|
||||
it('respond() should set default status 200 if not defined', function() {
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(200);
|
||||
expect(response).toBe('some-data');
|
||||
});
|
||||
|
||||
hb.expect('GET', '/url1').respond('some-data');
|
||||
hb.expect('GET', '/url2').respond('some-data', {'X-Header': 'true'});
|
||||
hb('GET', '/url1', null, callback);
|
||||
hb('GET', '/url2', null, callback);
|
||||
hb.flush();
|
||||
expect(callback).toHaveBeenCalled();
|
||||
expect(callback.callCount).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
it('then() should set default status 200 if not defined', function() {
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(200);
|
||||
expect(response).toBe('some-data');
|
||||
});
|
||||
|
||||
hb.when('GET', '/url1').then('some-data');
|
||||
hb.when('GET', '/url2').then('some-data', {'X-Header': 'true'});
|
||||
hb('GET', '/url1', null, callback);
|
||||
hb('GET', '/url2', null, callback);
|
||||
hb.flush();
|
||||
expect(callback).toHaveBeenCalled();
|
||||
expect(callback.callCount).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
it('should respond with definition if no response for expectation', function() {
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(201);
|
||||
expect(response).toBe('def-response');
|
||||
});
|
||||
|
||||
hb.when('GET').then(201, 'def-response');
|
||||
hb.expect('GET', '/some-url');
|
||||
|
||||
hb('GET', '/some-url', null, callback);
|
||||
hb.flush();
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
hb.verifyExpectations();
|
||||
});
|
||||
|
||||
|
||||
it('should throw an exception if no response defined', function() {
|
||||
hb.when('GET', '/test');
|
||||
expect(function() {
|
||||
hb('GET', '/test', null, callback);
|
||||
}).toThrow('No response defined !');
|
||||
});
|
||||
|
||||
|
||||
it('should throw an exception if no response for expection and no definition', function() {
|
||||
hb.expect('GET', '/url');
|
||||
expect(function() {
|
||||
hb('GET', '/url', null, callback);
|
||||
}).toThrow('No response defined !');
|
||||
});
|
||||
|
||||
|
||||
it('should respond undefined when JSONP method', function() {
|
||||
hb.when('JSONP', '/url1').then(200);
|
||||
hb.expect('JSONP', '/url2').respond(200);
|
||||
|
||||
expect(hb('JSONP', '/url1')).toBeUndefined();
|
||||
expect(hb('JSONP', '/url2')).toBeUndefined();
|
||||
});
|
||||
|
||||
|
||||
describe('verify', function() {
|
||||
|
||||
it('should throw exception if not all expectations were satisfied', function() {
|
||||
hb.expect('POST', '/u1', 'ddd').respond(201, '', {});
|
||||
hb.expect('GET', '/u2').respond(200, '', {});
|
||||
hb.expect('POST', '/u3').respond(201, '', {});
|
||||
|
||||
hb('POST', '/u1', 'ddd', noop, {});
|
||||
|
||||
expect(function() {hb.verifyExpectations();})
|
||||
.toThrow('Unsatisfied requests: GET /u2, POST /u3');
|
||||
});
|
||||
|
||||
|
||||
it('should do nothing when no expectation', function() {
|
||||
hb.when('DELETE', '/some').then(200, '');
|
||||
|
||||
expect(function() {hb.verifyExpectations();}).not.toThrow();
|
||||
});
|
||||
|
||||
|
||||
it('should do nothing when all expectations satisfied', function() {
|
||||
hb.expect('GET', '/u2').respond(200, '', {});
|
||||
hb.expect('POST', '/u3').respond(201, '', {});
|
||||
hb.when('DELETE', '/some').then(200, '');
|
||||
|
||||
hb('GET', '/u2', noop);
|
||||
hb('POST', '/u3', noop);
|
||||
|
||||
expect(function() {hb.verifyExpectations();}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('reset', function() {
|
||||
|
||||
it('should remove all expectations', function() {
|
||||
hb.expect('GET', '/u2').respond(200, '', {});
|
||||
hb.expect('POST', '/u3').respond(201, '', {});
|
||||
hb.resetExpectations();
|
||||
|
||||
expect(function() {hb.verifyExpectations();}).not.toThrow();
|
||||
});
|
||||
|
||||
|
||||
it('should remove all responses', function() {
|
||||
hb.expect('GET', '/url').respond(200, '', {});
|
||||
hb('GET', '/url', null, callback, {});
|
||||
hb.resetExpectations();
|
||||
hb.flush();
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('MockHttpExpectation', function() {
|
||||
|
||||
it('should accept url as regexp', function() {
|
||||
var exp = new MockHttpExpectation('GET', /^\/x/);
|
||||
|
||||
expect(exp.match('GET', '/x')).toBe(true);
|
||||
expect(exp.match('GET', '/xxx/x')).toBe(true);
|
||||
expect(exp.match('GET', 'x')).toBe(false);
|
||||
expect(exp.match('GET', 'a/x')).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should accept data as regexp', function() {
|
||||
var exp = new MockHttpExpectation('POST', '/url', /\{.*?\}/);
|
||||
|
||||
expect(exp.match('POST', '/url', '{"a": "aa"}')).toBe(true);
|
||||
expect(exp.match('POST', '/url', '{"one": "two"}')).toBe(true);
|
||||
expect(exp.match('POST', '/url', '{"one"')).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should ignore data only if undefined (not null or false)', function() {
|
||||
var exp = new MockHttpExpectation('POST', '/url', null);
|
||||
expect(exp.matchData(null)).toBe(true);
|
||||
expect(exp.matchData('some-data')).toBe(false);
|
||||
|
||||
exp = new MockHttpExpectation('POST', '/url', undefined);
|
||||
expect(exp.matchData(null)).toBe(true);
|
||||
expect(exp.matchData('some-data')).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should accept headers as function', function() {
|
||||
var exp = new MockHttpExpectation('GET', '/url', undefined, function(h) {
|
||||
return h['Content-Type'] == 'application/json';
|
||||
});
|
||||
|
||||
expect(exp.matchHeaders({})).toBe(false);
|
||||
expect(exp.matchHeaders({'Content-Type': 'application/json', 'X-Another': 'true'})).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user