Reputation: 9858
I am trying to write a unit test for a function that takes IncomingMessage
as a parameter. I understand it is a stream but I am unsure how to create a basic test dummy as the stream causes my tests to timeout
: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
My class
import { IncomingMessage } from 'http';
export class MyClass
example(request: IncomingMessage): void {
console.log(request.get('hello?'))
}
}
My test
it('test', () => {
const myclass = new MyClass();
const request = {
get: () => 'hello!'
} as unknown as IncomingMessage
const response = myclass.example(request);
expect(response).toEqual('hello!');
});
I assume I need to close the stream so how can I do that when casting a 'dummy' object to type IncomingMessage
?
I tried using
const request = {
get: () => 'hello'
} as unknown as IncomingMessage
request.setTimeout(1)
but then I get an error that the function is not found, which makes sense since the dummy is basically an empty object with only one mocked function
TypeError: request.setTimeout is not a function
In this case I assume I need to actually create a real IncomingMessage
? But I cannot find much documentation or examples on how to do this
What is the best way to create a real IncomingMessage
stream, close it quickly and have a mocked get
method? I think I would then need to mock a socket?
Or what is the correct way to test my class and function in this case?
Upvotes: 3
Views: 3413
Reputation: 409
If you're not using express
and using the built in http
library for node you can do the following:
Note: This will also work with express
too
import httpMocks from 'node-mocks-http';
import handleRequest from '../../../handlers/request';
describe('incoming message mock', () => {
it('working example', () => {
const mockRequest = httpMocks.createRequest({
method: 'POST',
url: '/my-fantastic-endpoint',
headers: {
'content-type': 'application/json',
'accept': 'application/json',
'content-length': '1',
'x-forwarded-for': '127.0.0.1',
},
});
mockRequest.destroy = jest.fn();
const mockResponse = httpMocks.createResponse();
handleRequest(mockRequest, mockResponse);
mockRequest.send({
example: 'hello!',
});
console.log(mockResponse._getData());
expect(true).toBe(true);
});
});
Upvotes: 1
Reputation: 456
Basically you need to mock your request object that can be done with below snippet:
function _mock_req() {
let req = {
get: jest.fn(() => 'hello!'),
};
return req;
}
Once mocking is done invoke it in your test case, here I'm using beforeEach
that will take care of the issue: openHandler- Async callback was not invoked
.
describe('http test', () => {
let req, res;
const myclass = new MyClass();
beforeEach((done) => {
req = _mock_req();
res = myclass.example(req);
done();
});
it('class test', () => {
expect(res).toEqual('hello!');
});
});
You also need to return request
from your class to test get passed. While executing test case your mocked request object will get return from MyClass
export class MyClass {
example(request: IncomingMessage): void {
console.log(request.get('hello?'));
return request.get('hello?')
}
}
Test case result:
Upvotes: 2