Testing HTTP interactions - Pragmatists/ng-test-runner GitHub Wiki
In contrast to stubbing HTTP requests, ng-test-runner
allows to fake http request to server.
To know difference between stubs, fakes and mocks visit Test Doubles – Fakes, Mocks and Stubs or Mocks Aren't Stubs.
By default HTTP communication is synchronous, as for most of the cases you don't need/want to include temporal dependencies in your tests. This saves you from writing obscure tick()
.
However, you can switch to asynchronous mode, if you feel you need to simulate network latency, for more complicated scenarios (ex. testing spinner).
Initialization
http([config])
Config:
respondImmediately: boolean - false
enables async mode; default : true
autoRespond: boolean - true
- respond immadietally, false
- respond after; default : true
respondAfter: number - response will be returned after x miliseconds, it demands disabled autoRespond
; default : 10
import { http, Server } from 'ng-test-runner';
let server: Server;
beforeEach(() => {
server = http();
});
afterEach(() => {
server.stop();
});
Creating fake
methodName(url, handler)
Creates fake server function for url. Possible method names : get
, put
, post
, delete
Parameters
Argument | Type | Description |
---|---|---|
url | string, RegExp | url or regexp to match http requests |
handler | function(Request, ...args: any[]) | function which will be call after matching http request |
Example
import test, { http, Server, expectThat } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('responds with specific code', async(() => {
// given:
const server = http();
const app = test(MyModule);
server.get('/greeting', req => {
req.sendJson({
message: 'Hello from server!'
});
});
// when:
const comp = app.run(MyComponent);
// then:
comp.verify(
expectThat.textOf('.greeting').isEqualTo('Hello from server!')
);
}));
Example
import test, { http, Server, expectThat } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('should send request to correct path', async(() => {
let receivedId;
server.put(/api\/test\/(\d+)/, (req, id) => {
receivedId = id;
req.sendStatus(200);
});
const comp = app.run(MyComponent);
comp.perform(
click.in('.update')
);
comp.verify(
() => expect(id).toEqual('321')
);
}));
stop()
Reset all created fakes.
Async mode
server
object allows to turn on async mode where waiting requests are resolving only in case of performing server.respond
action.
Example:
import test, { expectThat, http } from 'ng-test-runner';
it('resolves request after respond()', () => {
// given:
const server = http({autoRespond: true, respondImmediately: false});
const app = test(MyModule);
server.get('/greeting', req => req.sendStatus(200));
// when:
const comp = app.run(MyComponent);
comp.verify(
expectThat.textOf('.greeting').isEqualTo('Waiting for server response!')
);
comp.perform(
server.respond
);
comp.verify(
expectThat.textOf('.greeting').isEqualTo('Hello from server!')
);
});
Request
Req
object allows to verify sent request and to customize responses.
It's a generic type with two parameters Req<T = any, P = any>
, where T
is the type of request body and P
is the type of query params object. By default both are set to any
and there is no need to specify any of them if you don't need.
body()
Returns body of sent request.
Example
import test, { http, Server } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('body contains data from input', async(() => {
let body;
server.post('/create', req => {
body = req.body();
req.sendStatus(201);
});
const comp = app.run(MyComponent);
comp.perform(
type('John').in('.input-name'),
click.in('.send-button')
);
comp.verify(
() => expect(body.name).toEqual('John')
);
}));
header(name: string)
Returns value of header with given name
.
Example
import test, { http, Server } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('version in header is sent to backend', async(() => {
let versionHeader;
server.put('/update', req => {
versionHeader = req.header('If-Match');
req.sendStatus(200);
});
const comp = app.run(UpdatingComponent);
comp.perform(
type('Joe').in('.input-name'),
click.in('.update-button')
);
comp.verify(
() => expect(versionHeader).toEqual('1')
);
}));
query()
Returns data from request query string.
Example
import test, { http, Server } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('query should contain user selection', async(() => {
let query;
// for query like messages?name=Joe&status=SENT,ERROR&limit=10&offset=10&sort=name
server.get(/\/messages/, req => {
query = req.query();
req.sendJson([{
name: 'Joe',
status: 'SENT'
}, {
name: 'Joe',
status: 'ERROR'
}]);
});
const comp = app.run(FilteringComponent);
comp.perform(
type('Joe').in('.input-name'),
select('SENT').in('.status-checkboxes'),
select('ERROR').in('.status-checkboxes'),
click.in('.filter-button')
);
comp.verify(
() => expect(query.name).toEqual('Joe'),
() => expect(query.status).toEqual('ERROR,SENT'),
);
}));
sendJson(json: any, headers?: any)
Sends a json
as a JSON object in response. Optional headers
may be included.
Example
import test, { http, Server, expectThat } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('table should display players data in rows', async(() => {
server.get('/players', req => req.sendJson([{
name: 'Micheal',
score: 30
}, {
name: 'Karl',
score: 25
}])
);
const comp = app.run(ComponentThatFetchDataInNgOnInit);
comp.verify(
expectThat.textOf('.player-row:nth-of-type(1) .name').isEqualTo('Michael'),
expectThat.textOf('.player-row:nth-of-type(1) .score').isEqualTo('30'),
expectThat.textOf('.player-row:nth-of-type(2) .name').isEqualTo('Karl'),
expectThat.textOf('.player-row:nth-of-type(2) .score').isEqualTo('25')
);
}));
sendResponse(status: number, body: string, headers: any)
Sends reponse with specific status
, body
and headers
.
Example
import test, { http, Server, expectThat } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('id from location header should be displayed', async(() => {
server.post('/configuration', req => req.sendResponse(200, '', {Location: 'config/10'}));
const comp = app.run(MyComponent);
comp.perform(
click.in('.save-configuration')
);
comp.verify(
expectThat.textOf('.config .id').isEqualTo('10')
);
}));
sendStatus(status: number, json?: any, headers?: any)
Sends a specific status
in response. Optional json
body and headers
may be included.
Example
import test, { http, Server, expectThat } from 'ng-test-runner';
import { async } from '@angular/core/testing';
it('body contains data from input', async(() => {
let body;
server.post('/create', req => req.sendStatus(201));
const comp = app.run(MyComponent);
comp.perform(
type('John').in('.input-name'),
click.in('.send-button')
);
comp.verify(
expectThat.textOf('.status').isEqualTo('Success')
);
}));