getsaf / shallow-render

Angular testing made easy with shallow rendering and easy mocking. https://getsaf.github.io/shallow-render
MIT License
273 stars 25 forks source link

shallow-render 15.0.0 doesn't work with angular/material >=15.0 #238

Closed mtr20 closed 1 year ago

mtr20 commented 1 year ago

I've tried to upgrade angular 14(with angular/material) application to 15, and I'm getting diverse errors on shallow.render(): Error: MockOfCdkScrollable does not have a module def (ɵmod property) There are more such errors with different MockOfCdk..... (it's always some Cdk.... class). After .dontMock(CdkScrollable) I get sporadically error in tests : TypeError: this._scrollStrategyFactory is not a function Not all tests are affected.

After it, I've generated completely new angular 15 project. Shallow.render() worked just fine before adding angular/material. After adding angular/material into new angular 15 project, shallow.render() stop working with error: TypeError: rendererFactory.createRenderer is not a function

Timebutt commented 1 year ago

I'm seeing the exact same problem in my tests right now, I think the issues started happening with Angular version >=15.1.0.

getsaf commented 1 year ago

This may be fixed in the latest version(s) v14.2.3 or v15.0.1 It could be related to support for standalone components. See #239

LMK if this does fix things and hopefully we can get this issue closed out.

mtr20 commented 1 year ago

Just tried it(v15.0.1) in new angular project with material, unfortunately with same result : TypeError: rendererFactory.createRenderer is not a function

getsaf commented 1 year ago

I just reproduced the issue myself. If possible, could you just use the real Material components? They are usually pretty well self-contained.

I solved this locally with this global Shallow setup:

  Shallow.neverMock(RendererFactory2)
    // add all the material modules you use
    .neverMock(MatSlideToggleModule)
    // If you use the Animations Module
    .alwaysReplaceModule(BrowserAnimationsModule, NoopAnimationsModule);
getsaf commented 1 year ago

Just tried this again and it looks like the issue was the AnimationsModule.. Once I subbed in the NoopAnimationsModule, the test passed just fine.

Here's what I used for my test. I just followed the two-step getting started guid for Material here.

Does this solve the issue for you?

describe('AppComponent', () => {
  let shallow: Shallow<AppComponent>;

  beforeEach(async () => {
    shallow= new Shallow(AppComponent, AppModule)
      .replaceModule(RouterModule, RouterTestingModule)
      .replaceModule(BrowserAnimationsModule, NoopAnimationsModule);
  });

  it('should render the toggle', async () => {
    const {find} = await shallow.render();

    expect(find('mat-slide-toggle').nativeElement.textContent).toContain('Toggle me!');
  });
});
mtr20 commented 1 year ago

Hi

It does solve the Problem in new Angular Material project. I was hoping to not have to define all don't mock material modules manually. In Angular 15 + material there are other problems which I had to solve with rewrite the tests using Angular-Testbed instead of shallow-render. Fortunately it was just by 6 of 2500 tests the case. Unfortunately, I didn't have time to investigate it deeper to could deliver more details. Angular 15 update feels still a little bit unstable. Anyway, thank you for your answers.