As mentioned earlier by @Diaboloxx, it is important to mock out the HttpService
in your tests using the providers
setup.
For better test isolation and to prevent actual requests during testing, it's recommended to provide and mock out any dependencies that are being injected into your constructor.
I personally prefer using the mockDeep
function from 'jest-mock-extended' library for mocking providers, tracking calls made on them, and specifying return values. It also helps ensure type safety when mocking return data.
Additional Tip: It's good practice to verify that your dependencies are called with the expected parameters.
import { HttpService } from '@nestjs/axios'
import { Test, TestingModule } from '@nestjs/testing'
import { mockDeep } from 'jest-mock-extended'
import { of } from 'rxjs'
import { AxiosResponse } from 'axios'
import { MyService } from '@/services/my.service'
describe('MyService', () => {
let myService: MyService
const httpService = mockDeep<HttpService>()
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [myService],
providers: [
{
provide: HttpService,
useValue: httpService,
},
],
}).compile()
myService = app.get<MyService>(MyService)
})
describe('#myMethod', () => {
const response: AxiosResponse<unknown, any> = {
data: { hello: 'world' },
headers: {},
config: { url: 'http://localhost:3000/mockUrl' },
status: 200,
statusText: 'OK',
}
beforeEach(() => {
httpService.post.mockReturnValue(of(response))
})
it('should return "Hello World!"', async () => {
const result = await myService.myMethod({ code: 'value' })
expect(result).toEqual({ hello: 'world' })
})
it('calls httpService.post with the correct params', async () => {
await myService.myMethod({ code: 'value' })
expect(httpService.post).toHaveBeenLastCalledWith(
'someBaseUrl/param1/param2',
{ body: 'body' },
expect.objectContaining({
headers: {
header: 'header',
},
}),
)
})
})
})