Nest: Support for dynamic mocking frameworks

Created on 31 Oct 2018  Â·  11Comments  Â·  Source: nestjs/nest

I'm submitting a...


[ ] Regression 
[X] Bug report
[X] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior


When running e2e tests, app.init() throws the following the following exception if I override a provider with a dynamic mock.

    TypeError: instance.onModuleInit is not a function

      at MapIterator.Promise.all.iterare_1.default.map.filter.filter.map [as iteratee] (../node_modules/@nestjs/core/nest-application-context.js:64:47)
      at MapIterator.next (../node_modules/iterare/src/map.ts:11:39)
      at IteratorWithOperators.next (../node_modules/iterare/src/iterate.ts:21:28)
          at Function.all (<anonymous>)
      at NestApplication.callModuleInitHook (../node_modules/@nestjs/core/nest-application-context.js:60:23)
      at NestApplication.callInitHook (../node_modules/@nestjs/core/nest-application-context.js:51:24)
      at NestApplication.init (../node_modules/@nestjs/core/nest-application.js:96:20)

Expected behavior


The ablity to override providers with dynamic mocks.

Minimal reproduction of the problem with instructions


Just to establish some context...

  • the mocking api is ts-mockito
  • the exists method on the PageService is used by the controllers to determine if a page exists
describe('Page API', () => {
  let app: INestApplication;
  const mockPageService: PageService = mock(PageService);

  beforeAll(async () => {
    const mod = await Test.createTestingModule({
      imports: [PagesModule],
    })
      .overrideProvider(PageService)
      .useValue(instance(mockPageService))
      .compile();

    app = mod.createNestApplication();
    await app.init();  // <---- exception is thrown here
  });

  it('[GET] /pages', () => {
    return request(app.getHttpServer())
      .get('/pages')
      .expect(200);
  });

  describe('[GET] /pages/:slug', () => {
    beforeAll(() => {
      when(mockPageService.exists('non-existent-page')).thenReturn(false);
      when(mockPageService.exists('example-page')).thenReturn(true);
    });
    it('should return 4o4 when :slug cannot be found', () => {
      return request(app.getHttpServer())
        .get('/pages/non-existent-page')
        .expect(404);
    });

    it('should return 200 when :slug can be found', () => {
      return request(app.getHttpServer())
        .get('/pages/example-page')
        .expect(200);
    });
  });

  afterAll(async () => {
    await app.close();
  });
});

What is the motivation / use case for changing the behavior?


Dynamic mocks are awesome.

Environment


Nest version: 5.5.0


For Tooling issues:
- Node version: v8.11.1  
- Platform: Windows 10  

Others:

core type

Most helpful comment

The issue still remains. For further clarification, please see this branch of my repository.

Get same issue on nestjs 6.1.1

All 11 comments

I think this is related to #928

Nest supports dynamic mocking libraries. I think that your issue is rather related to a bug in the currently used version of the package. I'd suggest updating all Nest libs, especially @nestjs/core and @nestjs/testing.

The issue still remains. For further clarification, please see this branch of my repository.

928 was closed already, the issue is fixed in the 5.4.1 release. Have you tried with this version?

The issue still remains. For further clarification, please see this branch of my repository.

Get same issue on nestjs 6.1.1

Same issue, why was this closed?

I think because of inactivity. The project that I was using nestjs in became stale. Hence I haven’t pursued it, but I never found a fix.

On Aug 20, 2019, at 3:26 PM, Rafael Karayannopoulos notifications@github.com wrote:

Same issue, why was this closed?

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@nrhoffmann not really, you pointed out the problem and Nest team never pursued it.

Nest test module has problems with reflection, the real issue here is lacking of investigation and closing the issue without being certain of the solution, the problem persists, overriding a provider wrongly tries to invoke onModuleInit on an instance that clearly does not have it.

At least 4 people reported the same problem, some love for the testing? "need clarification" label was included based on a guess while an example was provided... Seriously!

I looked into it; it is actually a issue by Nest.
In the following function we check whether instance.onModuleInit is undefined.

https://github.com/nestjs/nest/blob/baa20004fccca575336d7455a3a3e754400cc0e9/packages/core/hooks/on-module-init.hook.ts#L16-L18

But (probably) due to the mocking library, instance.onModuleInit is null, therefore hasOnModuleInitHook returns true.

Changing it to return !isNil((instance as OnModuleInit).onModuleInit); will fix this issue.

Thanks a lot for your repository @nrhoffmann, it allowed me to get to the root cause of this issue quickly ! Sorry for your inconveniences and closing this issue. We review a lot of issues, so every now and then an issue gets closed, which should not have been :)

PR submitted #2790

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings