APIのUnitテストの入門
public.icon
Node.js(Express)でTSを使っているプロダクトのtestの導入方法 やらないこと
CI/CDに組み込むとかはやりません
やること
DBモック使用
ローカル実行のみ
Unit Testのみ
最初の導入としてはこれでいい気がする
$ npm install --save-dev jest @types/jest ts-jest jest-mock-extended
interfaceからMockを作ってくれる
Prismaをmockすると、そこに生えているメソッドがinterfaceになるので、Mockがとても楽になる
code:ts
// src/service/UserService.ts
export type CreateUserInput = { name: string };
export type User = { id: string; name: string };
export interface UserRepo {
findById(id: string): Promise<User | null>;
create(data: CreateUserInput): Promise<User>;
}
// こういうinterfaceをMockしたらいいのさ
export class UserService {
constructor(private readonly repo: UserRepo) {}
async getById(id: string) {
const u = await this.repo.findById(id);
if (!u) throw new Error("UserNotFound");
return u;
}
async register(input: CreateUserInput) {
if (!input.name.trim()) throw new Error("InvalidName");
return this.repo.create(input);
}
}
Prismaを使っている人なら、PrismaをMockしたらそこから生えているメソッドを丸々Mockにできるkinjyo.icon code:ts
it('ユーザーを正常に作成する', async () => {
const hashedPassword = 'hashedpassword';
const mockUser = {
id: BigInt(1),
email: signupData.email,
passwordHash: hashedPassword,
firstName: signupData.firstName,
lastName: signupData.lastName,
isAdmin: false,
};
//こんな感じで
prismaMock.user.findUnique.mockResolvedValue(null);
(mockedBcrypt.hash as jest.Mock).mockResolvedValue(hashedPassword);
prismaMock.user.create.mockResolvedValue(mockUser as any);
const result = await AuthService.signup(signupData);
expect(prismaMock.user.findUnique).toHaveBeenCalledWith({
where: { email: signupData.email }
});
expect(prismaMock.user.create).toHaveBeenCalledWith({
data: {
email: signupData.email,
passwordHash: hashedPassword,
firstName: signupData.firstName,
lastName: signupData.lastName,
firstNameKana: undefined,
lastNameKana: undefined,
}
});
expect(result.user.email).toBe(signupData.email);
expect(result.token).toBeDefined();
});