fbpx

I have been working a lot with NestJS lately and I have come across the “make sure that the argument HttpService at index [0] is available” error a few times when trying to test my code. This is a dependency issue and the solution is very simple. In this post, I will,

  1. talk about what the problem is
  2. share code that may cause this problem
  3. give a reason as to why it does
  4. and the simple solution to it

Background

In the last month, I have bee involved with building “modern” backend solutions using NestJS. Now for those of you who don’t know NestJS it’s a server-side Javascript/Typescript framework built on top of NodeJS, Express and inspired by Angular. The inspiration is to the point that for someone who’s worked with Angular can easily pick up NestJS without any dramas. Everything that you know from Angular, e.g. controllers, providers, guards etc are all there.

Problem

At work we have been using this tool called Nx to help with our monorepo strategy. What I mean is all the code for the NestJS project is generated using the Nx cli instead of the nest cli. As good as that tool is, what happens is when it generates the code, it also generates the unit tests with it. For each library generated using the following command

nx generate @nrwl/nest:library mylib –controller –service

It will generate the code that generates the controller, modules, Jest unit tests as well as a README file with the command run tests. The generated tests run fine and without any problems when you first generate it.

Querying an API

Say at some stage, we need to fetch data from an external API and we do that in the generated MylibService class. Example: we want to query a database for Chuck Norris jokes. The code for that should look something like,

import { Injectable, HttpService } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class MylibService {

    constructor(private httpService: HttpService) {}

    getJokes(): Observable<any> {
        const url = "http://api.icndb.com/jokes/random";
        return this.httpService.get(url).pipe(
            map(response => response.data)
        );
    }
}

In NesJS terminology we are using a provider HttpService that comes from the HttpModule. The code above works fine and as expected, however let’s look at the readme file and the test command that the nx generate tool generated for us. Let’s run that command, and…

nx test mylib

it will throw the following error,

Nest can't resolve dependencies of the MylibService (?). Please make sure that the argument HttpService at index [0] is available in the RootTestModule context.

Potential solutions:
- If HttpService is a provider, is it part of the current RootTestModule?
- If HttpService is exported from a separate @Module, is that module imported within RootTestModule?
@Module({
    imports: [ /* the Module containing HttpService */ ]
})

Remember, these problems are in the auto-generated tests, even before we write our own tests for it. However, let’s fix the errors in code before we start writing our custom tests.

Solution

The two solutions would be

  1. Get rid of the test code that was auto-generated: how will this help us? I mean, we will face this problem when we try to unit test our code
  2. Or we can actually fix the problem and it’s not that hard so we may as well fix it

The auto-generated mylib.service.spec.ts file looks like this,

import { Test } from '@nestjs/testing';
import { MylibService } from './mylib.service';

describe('MylibService', () => {
  let service: MylibService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [MylibService],
    }).compile();

    service = module.get(MylibService);
  });

  it('should be defined', () => {
    expect(service).toBeTruthy();
  });
});

What does the error tell us?

If HttpService is a provider, is it part of the current RootTestModule?

The error is telling us that the test cannot find the HttpService class to inject into MylibService when initialising it. Now, where does the HttpService class come from and how does the MylibService.ts know about it? It comes from the HttpModule library and we inject it into the MylibModule for it to know about it.

Therefore to solve this problem, all we need to do is import the HttpModule in our test by changing the above code as follows,

import { Test } from '@nestjs/testing';
import { MylibService } from './mylib.service';
import { HttpModule } from '@nestjs/common';

describe('MylibService', () => {
  let service: MylibService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [MylibService],
      imports: [HttpModule]
    }).compile();

    service = module.get(MylibService);
  });

  it('should be defined', () => {
    expect(service).toBeTruthy();
  });
});

That’s it! A simple solution that works.

Conclusion

I often feel that I don’t read or analyse error messages as well as I should. I mean, this error message was actually quite simple and descriptive. Almost 70% of the times, solutions to some of the errors we face during development are fairly straight forward. 

I hope to follow up this post with another post that cover different test scenarios with Jest.

Like the blog? Subscribe for updates

As usual, if you find any of my posts useful support me by  buying or even trying one of my apps on the App Store. 

https://mydaytodo.com/apps/

Also, if you can leave a review on the App Store or Google Play Store, that would help too.

Categories: Javascript

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *