前提・実現したいこと
Express(TypeScript)を用いたAPIサーバの開発をしています。
DBにMongoDBを使い、ORMとしてmongooseを使っています。
一ヶ月前ほどからJestを用いたテストを書き始めたのですが、モック化がうまくできず、
悩んだのですが解決しないため質問させて頂きます。
発生している問題・エラーメッセージ
Expressのルーティングに対応する処理をコントローラーとして分離をしています。
今回はusersControllerのloginメソッドに対して、モックのリクエストとレスポンス、NextFunctionなどを引数として渡し、正しいステータスコードが得れるかどうかというテストを書いています。
その中で、mongooseのスキーマUserModelを使用し、UserModel.findById()をする箇所があるのですが、それをモック化してもundefinedしか返りません。
該当のソースコード
userController.ts内の該当コード
TypeScript
1login: () => { 2~~ 3 user = await UserModel.findById(Number(loginUser.id)).exec(); 4~~ 5}
自動モックで使用されるsrc/models/mocks/userModel.tsのコード
TypeScript
1import { UsersRegisterInput } from "@shared/user"; 2class UserModel { 3 private hasError = false; 4 constructor(user: UsersRegisterInput) { 5 if (user.name == "") { 6 this.hasError = true; 7 } 8 } 9 save(fn: any): void { 10 fn(this.hasError); 11 } 12 13 findById(id: number): Promise<any> { 14 return new Promise((resolve, reject) => { 15 resolve({ 16 _id: id, 17 name: "Test User", 18 password: "0000" 19 }); 20 }); 21 } 22} 23export default UserModel;
また、src/models/userModel.tsのソースコードは省きます
試したこと
jestの公式ドキュメントに従い、new演算子を使うために自動モックでテストを作りました。
今回の問題とは違う箇所でnew UserModel()のモック化をし、インスタンスに対して、save()メソッドを使うテストは、上記のuserModel.tsでうまくいきました。
この要領で、class UserModel内にfindByIdメソッドを作成すれば、controllerの処理で使われるfindByIdにモックの値を流せると考えました。
それで上記のコードのようになったのですが、うまく動作しません。
そもそもTypeScriptに対する理解が足りていないのかもしれません。
クラスメソッドのような形で使用できると考えていたのですが間違っているのでしょうか。
また、更に良い手法や、そもそもが間違っていたり、ベストプラクティス等があれば教えて頂けると幸いです。
情報が足りていない場合、ご指摘ください、すぐに追記します。
よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
- mongodb 3.6.6
- mongoose 5.12.6
- express 4.16.1
- jest 27.0.6
- typescript 4.1.6
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。