Try   HackMD

Unit Testing (Jest)

VSCode tool , 可以直接幫忙你測試一個 test ,不用在 npm run test
https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest
提示寫法
https://marketplace.visualstudio.com/items?itemName=andys8.jest-snippets

Basic

toBeTruthy():確認是為為 true 如果為 false, 0, '',null , undefine, NaN,為false

Expect · Jest

expect 系列,相關的 function

前端測試框架Jest系列教程 Expect(驗證)

toHaveBeenCalledWith():

可以多看 ssr 專案中 notifications ,should send get /config/getNotifications

it('should send get /config/getNotifications', () => {
        const apiSpy = jest.spyOn(apiService, 'get'); // apiService 打 api-service
        service.getNotifications();
        expect(apiSpy).toHaveBeenCalledWith('/config/getNotifications');
});

mockReturnValue():

Accepts a value that will be returned whenever the mock function is called.

可以 return 所設定的值

jest.spyOn(apiService, 'post').mockReturnValue(
            throwError({
                error: {
                    // email已經存在
                    ReturnCode: 40032,
                },
            })
        );

測試環境下拿到 component 實體

import { HeaderLeftComponent } from './header-left.component';
describe('HeaderLeftComponent', () => {
		let fixture: ComponentFixture<HeaderLeftComponent>;
		// const component = fixture.componentInstance
		it('test sum function', () => {
        expect(fixture.componentInstance.sum(1, 2)).toBe(3);
    });
}
// click 的寫法
fixture = TestBed.createComponent(HeaderLeftComponent);

const menu = fixture.debugElement.nativeElement.querySelector('header-hamburger');
menu.click();

...

expect(...).toBe(...)

call service 的 function 來用

const video = {
  play() {
    return true;
  },
};

module.exports = video;

//

const video = require('./video');

test('plays video', () => {
  const spy = jest.spyOn(video, 'play');
  const isPlaying = video.play();

  expect(spy).toHaveBeenCalled();
  expect(isPlaying).toBe(true);

  spy.mockRestore(); // 為了要回復狀態用的
});

The Jest Object · Jest

非同步測試

Jest:非同步測試

測試場景

QA

Q:What is the difference between it and test in Jest ?

看起來是一樣的東西

What is the difference between 'it' and 'test' in Jest?

引用物件的東西

jest.spyOn(object, methodName)

The Jest Object · Jest

reference

十分鐘上手前端單元測試 - 使用 Jest

jest function

JEST 單元測試學習筆記 | Mock Functions

寫 unit test 的想法

91 的 Unit Test實戰營心得

引入完整的 angular

如果有引用 dialog 時

TestBed.configureTestingModule({
            declarations: [GeneralDialogComponent],
            imports: [
                MatDialogModule,
                HttpClientModule,
                BrowserModule,
                TranslateModule.forRoot({}), //  pipe 'translate'
                RouterTestingModule.withRoutes([]),
                GoogleTagManagerModule.forRoot({
                    id: environment.tagManagerID,
                }),
                BrowserAnimationsModule,
            ],
        }).overrideModule(BrowserModule, {
            set: {
                entryComponents: [GeneralDialogComponent],
            },
        });

// 需要加 overrideModule

身份認證的寫法

可以去看 auth.spec.ts 的寫法

import { ApiService } from './api.service';
import { ApiSystemService } from './api/api-system.service';
import { AuthService } from './auth.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed } from '@angular/core/testing';
import { of } from 'rxjs';

describe('AuthService', () => {
    let service: AuthService;
    let apiService: ApiService;
    let apiSystemService: ApiSystemService;
    let apiSpy = null;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([])],
            providers: [ApiService],
        });
        service = TestBed.inject(AuthService);
        apiService = TestBed.inject(ApiService);
        apiSystemService = TestBed.inject(ApiSystemService);
        apiSpy = jest.spyOn(apiSystemService, 'getCheckAuth').mockReturnValue(
            of({
                data: {
                    config: {
                        user: { id: '1', timezone: '+8' },
                        supplier: { id: '2', status: 'Inactive' },
                    },
                },
            })
        );
    });

    it('should be created', () => {
        expect(service).toBeTruthy();
    });

    it('should send get /config/checkAuth', () => {
        service.initUserRoles();
        expect(apiSpy).toBeCalledTimes(1);
    });

    it('should get userId', () => {
        service.initUserRoles();
        expect(service.userId).toBe('1');
    });

    it('should get supplierId', () => {
        service.initUserRoles();
        expect(service.supplierId).toBe('2');
    });

    it('should get userTimezone', () => {
        service.initUserRoles();
        expect(service.userTimezone).toBe('+8');
    });

    it('should get isLogin', () => {
        service.initUserRoles();
        expect(service.isLogin()).toBeTruthy();
    });

    it('should get isActiveSupplier', () => {
        service.initUserRoles();
        expect(service.isActiveSupplier()).toBeFalsy();
    });
});

正規驗證可以看 validation.server.spec.ts