Components: No documentation exists for Jasmine unit tests of Angular components containing @angular/material

Created on 16 Feb 2017  路  12Comments  路  Source: angular/components

Bug, feature request, or proposal:

documentation non-existant

What is the expected behavior?

Angular devdocs or Quickstart or angular/material2 or all of these should have a description of how to set up Jasmine unit tests for components that use angular/material2

What is the current behavior?

The current Angular Quickstart has a Jasmine test that works. If you put the Hello Angular statement inside md-toolbar, the test fails with statements about md-toolbar is not a component (even though it is registered in app.module and systemjs.config) and the test did not compile, etc.

What are the steps to reproduce?

Put Quickstart's Hello Angular inside md-toolbar

Providing a Plunker (or similar) is the best way to get the team to see your issue.
Plunker template: http://plnkr.co/edit/o077B6uEiiIgkC0S06dd

What is the use-case or motivation for changing an existing behavior?

It should not be necessary to spend hours tracking down angular/material problems.

Which versions of Angular, Material, OS, browsers are affected?

Using the current Angular Quickstart, existing documentation for Angular and angular/material

Is there anything else we should know?

docs feature help wanted

Most helpful comment

I can add some of the things I've come across which might help out others looking for info. Hopefully they are helpful, or alternatively others can suggest better ways of doing things

Add to the test bed

The most important thing is to include the MaterialModule in the imports of your test bed

import { MaterialModule } from '@angular/material';

TestBed.configureTestingModule({
    imports: [MaterialModule.forRoot()]
});

md-select
When trying to select an item from an md-select, I was able to click the select and then one of the md-option elements, however the md-options did not disappear, so if you have multiple md-selects on a form, you need to be aware of that.

I use the following utility method, whenever I need to select from an md-select in a component test

static pickFromMdSelect(cssSelector: string, itemIdx: string, fixture: ComponentFixture<any>, selectIdx?: string) {
    fixture.debugElement.query(By.css(cssSelector + ' .mat-select-trigger')).nativeElement.click();
    fixture.detectChanges();

    let selector = 'md-option:nth-child(' + itemIdx + ')';
    if (selectIdx) {
         selector = 'div.cdk-overlay-pane:nth-child(' + selectIdx + ') ' + selector;
    }

    fixture.debugElement.query(By.css(selector)).nativeElement.click();
    fixture.detectChanges();
}

md-dialog

For testing that some action opens a dialog, I added a mock to the list of providers and used jasmine's spy on to assert on it. Its important that the spyOn is before the configuration of the testing module

let dialogMock = {
    open: function(a, b) {}
};

spyOn(dialogMock, 'close');

TestBed.configureTestingModule({
     providers: [{
        provide: MdDialog,
        useValue: dialogMock
    }]
})

expect(dialogMock.open).toHaveBeenCalled();

I also had a case where I wanted to assert that some action happened after the dialog was closed, so I used the following jasmine spy

spyOn(dialogMock, 'open').and.returnValue({
    afterClosed: function() {
        return Observable.of(true);
    }
});

All 12 comments

@mLaird have you been able to get any Jasmine tests working?
I'm guessing a "Jasmine guide" could be put under guides.

While those docs aren't write, why don't put a good examples here or links that help solve the problem listed above?

I can add some of the things I've come across which might help out others looking for info. Hopefully they are helpful, or alternatively others can suggest better ways of doing things

Add to the test bed

The most important thing is to include the MaterialModule in the imports of your test bed

import { MaterialModule } from '@angular/material';

TestBed.configureTestingModule({
    imports: [MaterialModule.forRoot()]
});

md-select
When trying to select an item from an md-select, I was able to click the select and then one of the md-option elements, however the md-options did not disappear, so if you have multiple md-selects on a form, you need to be aware of that.

I use the following utility method, whenever I need to select from an md-select in a component test

static pickFromMdSelect(cssSelector: string, itemIdx: string, fixture: ComponentFixture<any>, selectIdx?: string) {
    fixture.debugElement.query(By.css(cssSelector + ' .mat-select-trigger')).nativeElement.click();
    fixture.detectChanges();

    let selector = 'md-option:nth-child(' + itemIdx + ')';
    if (selectIdx) {
         selector = 'div.cdk-overlay-pane:nth-child(' + selectIdx + ') ' + selector;
    }

    fixture.debugElement.query(By.css(selector)).nativeElement.click();
    fixture.detectChanges();
}

md-dialog

For testing that some action opens a dialog, I added a mock to the list of providers and used jasmine's spy on to assert on it. Its important that the spyOn is before the configuration of the testing module

let dialogMock = {
    open: function(a, b) {}
};

spyOn(dialogMock, 'close');

TestBed.configureTestingModule({
     providers: [{
        provide: MdDialog,
        useValue: dialogMock
    }]
})

expect(dialogMock.open).toHaveBeenCalled();

I also had a case where I wanted to assert that some action happened after the dialog was closed, so I used the following jasmine spy

spyOn(dialogMock, 'open').and.returnValue({
    afterClosed: function() {
        return Observable.of(true);
    }
});

Tracking via #4056

@jelbourn, the issue you referenced as tracking is about theming and testing. Not only unit test although you've written there that you should write testing docs, etc...

Here is the thing, we work with angular material in quite a few projects which are already in production and the team is growing so we're adding unit test to our workflow (should have done it earlier) and the situation with angular material is a pain.

Any update on the subject or things we could help working on ?

Edit: Just saw the number of upvotes on your comments saying you should add testing docs, almost 70, I really think this needs to be reprioritized.

I am with @MonsieurMan on this, I've been struggling with adding tests to our app and can't find any documentation, I imported my custom material module in my spec and still see a ton of errors like this one

'mat-spinner' is not a known element:
1. If 'mat-spinner' is an Angular component, then verify that it is part of this module.

I can't find any docs nor can I find an actual app on github that has proper testing to see how they do it, asked on reddit too, no answers.

@Lakston
If it can help you, I ended up adding

    TestBed.configureTestingModule({
    ...
   // this line
      schemas: [NO_ERRORS_SCHEMA],
    ...
    }).compileComponents();
  }));

to remove errors as it is unit testing and we shouldn't depend on anything external after all, but still, it bugs me, haha.

Ha, I did too this morning and the material errors are gone (Yay !) but now I have the same type of errors with the children components used in the component I'm testing.

I have no idea what I'm doing :)

image

In angular 6 i am getting this error any idea, how to solve this in spec.ts for testing

@gseabrook Could you also please write few example test cases for material table?

image

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings