[解決済み] データベースクエリを使ったオブジェクトのユニットテスト方法
2022-04-29 02:39:08
質問
しかし、私のファイルの70%以上はデータベースへのアクセス(一部は読み込み、一部は書き込み)を含んでおり、これらのファイルのユニットテストをどのように書けばよいのかわかりません。
私はPHPとPythonを使用していますが、データベースアクセスを使用するほとんどの/すべての言語に当てはまる質問だと思います。
どのように解決するのですか?
データベースへの呼び出しをモック化することをお勧めします。 モックとは、基本的に、メソッドを呼び出そうとしているオブジェクトに似ているオブジェクトのことで、呼び出し元が利用できるプロパティやメソッドなどが同じという意味で、モックと呼びます。 しかし、特定のメソッドが呼び出されたときに行うようにプログラムされているアクションを実行する代わりに、それを完全にスキップして、ただ結果を返します。この結果は、通常、前もって定義しておく。
モッキングのためにオブジェクトをセットアップするには、おそらく次の疑似コードのように、ある種の制御の逆転や依存性の注入パターンを使用する必要があります。
class Bar
{
private FooDataProvider _dataProvider;
public instantiate(FooDataProvider dataProvider) {
_dataProvider = dataProvider;
}
public getAllFoos() {
// instead of calling Foo.GetAll() here, we are introducing an extra layer of abstraction
return _dataProvider.GetAllFoos();
}
}
class FooDataProvider
{
public Foo[] GetAllFoos() {
return Foo.GetAll();
}
}
ユニットテストでは、FooDataProvider のモックを作成し、実際にデータベースを叩くことなく GetAllFoos メソッドを呼び出せるようにします。
class BarTests
{
public TestGetAllFoos() {
// here we set up our mock FooDataProvider
mockRepository = MockingFramework.new()
mockFooDataProvider = mockRepository.CreateMockOfType(FooDataProvider);
// create a new array of Foo objects
testFooArray = new Foo[] {Foo.new(), Foo.new(), Foo.new()}
// the next statement will cause testFooArray to be returned every time we call FooDAtaProvider.GetAllFoos,
// instead of calling to the database and returning whatever is in there
// ExpectCallTo and Returns are methods provided by our imaginary mocking framework
ExpectCallTo(mockFooDataProvider.GetAllFoos).Returns(testFooArray)
// now begins our actual unit test
testBar = new Bar(mockFooDataProvider)
baz = testBar.GetAllFoos()
// baz should now equal the testFooArray object we created earlier
Assert.AreEqual(3, baz.length)
}
}
よくあるモッキングシナリオを簡単に説明します。 もちろん、実際のデータベース呼び出しもユニットテストしたいでしょうし、そのためにはデータベースを叩く必要があります。
関連
-
SQLSERVER エラーのリターンコードの意味一覧表
-
ORA-01034 を解決する: ORACLE は利用できません ORA-27101: 共有メモリ領域が存在しない
-
[解決済み] DynamoDBから大量のアイテムを削除したいのですが、おすすめの方法はありますか?
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] TDDのためのJavaScriptユニットテストツール
-
[解決済み] C# "internal "アクセス修飾子でユニットテストを行う場合
-
[解決済み] postgresql のセッション/接続を切断する
-
[解決済み] ディレクトリ内のすべてのPythonユニットテストを実行するにはどうすればよいですか?
-
[解決済み] データベース駆動型アプリケーションのユニットテストに最適な戦略とは?
-
Net connection pool configuration Timeout expired. 操作の完了前にタイムアウト時間が経過したか、サーバーが応答していない。"
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Hibernateでhibernate.propertiesが見つからない問題とデータベース方言の更新の問題
-
ORA-06550 "の解決策。1 行目、7 列目"
-
SSISエラーコード DTS_E_OLEDBERROR.an OLE DBエラーが発生しました。エラーコード 0x80040E21 備考
-
mysql: この操作には (少なくとも 1 つの) RELOAD 権限が必要です。
-
sql common mistake of incorrect predicate orderConversion failed when converting varchar value 'abc' to data type int
-
MySQL cumsum(累積)の実装
-
[解決済み] DynamoDBから大量のアイテムを削除したいのですが、おすすめの方法はありますか?
-
[解決済み] postgresql のセッション/接続を切断する
-
[解決済み】シャーディングとは何ですか、なぜそれが重要なのですか?
-
[解決済み] VARCHAR(255) が(他の長さではなく)頻繁に使用されているのを見るのは、何か理由があるのでしょうか?