https://zenn.dev/nananaoto/articles/64debb8f918805
ユニットテストでは、実行速度観点からも Infrastructure 層はモックすることが多いでしょう。 モックにもいくつか方法があり、テストライブラリでモックする方法やテスト用のクラスを使用して差し替えるなどがあります。
そこで、今回は下記 2 つの方法を比較してみます。
今回はユーザ情報を更新するユースケースを例に考えていきます。
具体的な実装は下記になります。
User
Class
UserRepository
Interface
UserMySQLRepository
Class
UpdateUser
Class
// ユーザのドメインモデル
export class User {
constructor(public id: string, public name: string, public email: string) {}
changeName(name: string): User {
return new User(this.id, name, this.email);
}
changeEmail(email: string): User {
return new User(this.id, this.name, email);
}
}
// ユーザを永続化するための Repository のインターフェース
export interface UserRepository {
findById(id: string): Promise<User | undefined>;
update(user: User): Promise<void>;
}
// MySQL に永続化するための Repository の実装
export class UserMySQLRepository implements UserRepository {
findById(_id: string): Promise<User | undefined> {
// MySQLのデータベースからユーザを取得する
throw new Error('Method not implemented.');
}
update(_user: User): Promise<void> {
// MySQLのデータベースにユーザを更新する
throw new Error('Method not implemented.');
}
}
// ユーザ情報を更新するユースケース
export class UpdateUser {
constructor(private userRepository: UserRepository) {}
async execute(userId: string, updateParam: { name: string; email: string }): Promise<void> {
const user = await this.userRepository.findById(userId);
if (!user) {
throw new Error('ユーザーが存在しません');
}
const updatedUser = user.changeName(updateParam.name).changeEmail(updateParam.email);
await this.userRepository.update(updatedUser);
}
}