使用 Jest 在 Angular 测试中模拟 Typescript 类中的静态方法

Sob*_*raz 7 unit-testing typescript jestjs angular

我想在组件的测试中使用静态方法模拟一个简单的 Typescript 类。我正在使用 Angular 8 和 jest 24.9.0 在尝试不同的方法并多次阅读 jest 文档后,它仍然无法工作......

这是我的代码:

惊人的组件.ts

import { Component, OnInit } from '@angular/core';
import { SimpleClass } from '../SimpleClass';

@Component({
    selector: 'app-amazing',
    templateUrl: './amazing.component.html',
    styleUrls: ['./amazing.component.scss']
})
export class AmazingComponent implements OnInit {
    message = 'default msg';
    constructor() {}

    ngOnInit() {
        this.message = SimpleClass.staticMethod('Bob');
    }
}
Run Code Online (Sandbox Code Playgroud)

惊人的组件.html

<p>{{ message }}</p>
Run Code Online (Sandbox Code Playgroud)

简单类.ts

export class SimpleClass {
    static staticMethod(myParam: string) {
        return 'Hello ' + myParam;
    }
}
Run Code Online (Sandbox Code Playgroud)

惊人的组件规格

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AmazingComponent } from './amazing.component';
import { By } from '@angular/platform-browser';

describe('AmazingComponent', () => {
    let component: AmazingComponent;
    let fixture: ComponentFixture<AmazingComponent>;

    jest.mock('../SimpleClass', () => ({
        default: class {
            public static staticMethod(param) {
                return 'MOCK MSG ' + param;
            }
        }
    }));

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [AmazingComponent]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(AmazingComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('should display the message transformed', async(() => {
        fixture.whenStable().then(() => {
            fixture.detectChanges();
            const message = fixture.debugElement.query(By.css('p'));
            expect(message.nativeElement.textContent).toEqual('MOCK MSG Bob');
        });
    }));
});
Run Code Online (Sandbox Code Playgroud)

结果 :

Error: Uncaught (in promise): Error: expect(received).toEqual(expected) // deep equality

Expected: "MOCK MSG Bob"
Received: "Hello Bob"
Run Code Online (Sandbox Code Playgroud)

看来我的模拟不起作用,但我不明白原因......知道吗?

=======================================

问题解决了 !

我必须将 jest.mock 放在描述之外,就在导入之后。并通过在 jest.Mocked 中转换模拟对象来模拟所需函数的实现。

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AmazingComponent } from './amazing.component';
import { By } from '@angular/platform-browser';
import { SimpleClass } from '../SimpleClass';

jest.mock('../SimpleClass');

describe('AmazingComponent', () => {
    let component: AmazingComponent;
    let fixture: ComponentFixture<AmazingComponent>;
    const MockSimpleClass = SimpleClass as jest.Mocked<typeof SimpleClass>;
    MockSimpleClass.staticMethod.mockImplementation((param) => 'MOCK MSG ' + param);

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [AmazingComponent]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(AmazingComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('should display the message transformed', async(() => {
        fixture.whenStable().then(() => {
            fixture.detectChanges();
            const message = fixture.debugElement.query(By.css('p'));
            expect(message.nativeElement.textContent).toEqual('MOCK MSG Bob');
        });
    }));
});

Run Code Online (Sandbox Code Playgroud)