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

Mocking pipes not working properly #181

Closed pheinicke closed 4 years ago

pheinicke commented 4 years ago

Hi!

I've written a pipe that I use in a lot of places in my project. All but one of my tests worked perfectly. This one test is for a component that calls #transform in the JS-code. All the other places I use that pipe are directly in the html-templates. Apparently, the mocked pipe does not have a "transform"-function.

The pipe:

@Pipe({
    name: 'profileName'
})
export class ProfileNamePipe implements PipeTransform {
    constructor(private i18NextPipe: I18NextPipe) {}

    transform(profile?: Profile): string {
        // doing stuff
        return '';
    }
}

The component:

@Component({
    selector: 'app-profile-search-result-teaser',
    templateUrl: './profile-search-result-teaser.component.html',
    styleUrls: ['./profile-search-result-teaser.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProfileSearchResultTeaserComponent {
    @Input() teaser: ProfileSearchResultTeaser;
    @Output() teaserClick = new EventEmitter<ProfileSearchResultTeaser>();

    constructor(private profileNamePipe: ProfileNamePipe) {}

    prefixedProfileName(name: string): string {
        return this.profileNamePipe.transform({
            ...toProfile(this.teaser),
            name
        });
    }
}

The test:

describe('ProfileSearchResultTeaserComponent', () => {
    const teaser: ProfileSearchResultTeaser = {
        ...
    };
    let shallow: Shallow<ProfileSearchResultTeaserComponent>;

    beforeEach(() => {
        shallow = new Shallow(ProfileSearchResultTeaserComponent, SearchModule);
    });

    it('should create', async () => {
        const { fixture } = await shallow.render({ bind: { teaser } });
        expect(fixture).toBeTruthy();
    });
});

When running the test, it fails with the error "TypeError: this.profileNamePipe.transform is not a function". this.profileNamePipe in this case is a MockOfProfileNamePipe. The error disappears when I

It does not disappear if I use .mockPipe(ProfileNamePipe, () => '').

Any help is, as always, greatly appreciated. If I can provide anything to help, please tell. Peter

getsaf commented 4 years ago

It looks like in this case, we have the ProfileNamePipe setup as a declaration and a provider in the module. When this happens, Angular treats them as two separate things.

I can detect this and make Shallow respect the mockPipe in both cases. This seems to be the right thing to do for consistency in the library too. I should be able to get this feature out over the weekend.

Thanks for submitting this, I'll let you know when it's added!

getsaf commented 4 years ago

Just pushed a fix, try v10.1.4

pheinicke commented 4 years ago

Thank you, it works!