Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use overrideProvider() to override undefined value #4743

Closed
andreialecu opened this issue May 6, 2020 · 3 comments
Closed

Cannot use overrideProvider() to override undefined value #4743

andreialecu opened this issue May 6, 2020 · 3 comments
Labels
needs triage This issue has not been looked into

Comments

@andreialecu
Copy link
Contributor

Bug Report

Current behavior

Seems that if a provider has an undefined initial value, it cannot be overriden using overrideProvider().

Input Code

const mongoUriProvider = {
  provide: "MONGO_URI",
  useValue: process.env.MONGO_URI, // this is undefined in TEST env
};

@Module({
  providers: [mongoUriProvider, ConfigService],
  exports: [ConfigService],
})
export class ConfigModule {}

Then in tests:

    const module: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    })
      .overrideProvider("MONGO_URI")
      .useValue(someConnectionString)
      .compile();

Everything fails because MONGO_URI is not defined:

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

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

This took a couple of hours of troubleshooting to figure out. A workaround is to provide a default non-undefined value. null seems to work:

const mongoUriProvider = {
  provide: "MONGO_URI",
  useValue: process.env.MONGO_URI || null,
};

Expected behavior

Should be able to override the provider during tests even if it is set to undefined.

At a minimum, a warning should be emitted that an undefined provider has been set, if it cannot be fixed for other reasons.

Environment


Nest version: 7.0.9
@andreialecu andreialecu added the needs triage This issue has not been looked into label May 6, 2020
@kamilmysliwiec
Copy link
Member

Thanks for reporting!

This was already discussed in the past. You can't bind undefined values to the container (undefined has simply too many meanings, we can't determine whether you did it on purpose or not) so it's not really an issue with the overrideProvider() method.

@andreialecu
Copy link
Contributor Author

andreialecu commented May 7, 2020

Could overrideProvider at least log an error that the token wasn't found and provide an explanation to check whether it is set to an undefined value?

You can't bind undefined values to the container

But you can. :) And it results in this sort of issue. Maybe just throw an error on initialization if an undefined provider is detected?

I feel this behavior is very unexpected and not documented anywhere and just leads into a lot of confusion.

@andreialecu
Copy link
Contributor Author

Here's an alternative:

If ValueProvider is defined like this:

export interface ValueProvider<T = string | number | boolean | symbol | bigint | object | null> {
    /**
     * Injection token
     */
    provide: string | symbol | Type<any> | Abstract<any> | Function;
    /**
     * Instance of a provider to be injected.
     */
    useValue: T;
}

It will at least show a compilation error in typescript strict mode:

image

Not sure if anything can be done about non-strict mode.

Some relevant discussion here: microsoft/TypeScript#7648

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage This issue has not been looked into
Projects
None yet
Development

No branches or pull requests

2 participants