AutoFixtureで依存関係をモックする
-
21-12-2019 - |
質問
私は最近AutoFixture+AutoMoqを使い始めましたが、私は次のインスタンスを作成しようとしています Func<IDbConnection>
(すなわち、接続ファクトリ)。
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();
これはかなりうまくいくようです:
- テスト中の私のシステムはデリゲートを呼び出すことができ、それはのモックを取得します
IDbConnection
- 私はそれから呼び出すことができます
CreateCommand
, 、それは私のモックを取得しますIDbCommand
- 私はそれから呼び出すことができます
ExecuteReader
, 、それは私のモックを取得しますIDataReader
私は今のモックに追加のセットアップを実行したい IDataReader
, 、それを返すようにするなど true
とき Read()
と呼ばれる。
私が読んだことから、私は使用する必要があります Freeze
このために:
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
しかし、これは私の期待を満たしていないようです。私が電話するとき IDbCommand.ExecuteReader
, 、私はちょうど凍った/設定したものとは異なる読者を得るでしょう。
ここに例があります:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
//true - Create<IDataReader> retrieves the data reader I just mocked
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDataReader>());
//false - IDbCommand returns a different instance of IDataReader
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
私は何が間違っているのですか?次のような他の備品を入手するにはどうすればよいですか IDbCommand
, 、モックされたインスタンスを使用するには IDataReader
?
解決
3.20.0以降では、以下を使用できます AutoConfiguredMoqCustomization
.これにより、メンバーの戻り値がAutoFixtureによって生成されるように、すべてのモックが自動的に設定されます。
例:, IDbConnetion.CreateCommand
を返すように自動的に設定されます。 IDbCommand
フィクスチャから、そして IDbCommand.ExecuteReader
を返すように自動的に設定されます。 IDataReader
フィクスチャから。
これらのテストはすべて今合格するはずです:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
//all pass
Assert.Same(dataReaderMock.Object, fixture.Create<IDataReader>());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbConnection>().CreateCommand().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<Func<IDbConnection>>()().CreateCommand().ExecuteReader());
他のヒント
Freeze
をMock<IDbCommand>
にも必要にしておく必要があります。
テストのアレンジフェーズに次のものを追加した場合、テストは次のとおりです。
var dbCommandStub =
fixture
.Freeze<Mock<IDbCommand>>()
.Setup(x => x.ExecuteReader())
.Returns(dataReaderMock.Object);
. Nikosからの解決策は、私は私がado.netをモッキングすることをお勧めしません。
あなたのテストはおそらく理解し、維持し、あなたにあなたのテストがあなたに与えるべき自信を与えないでしょう。
私はそれが遅いとしてもデータベースにすべての道を行くことによってあなたのデータ層のテストを検討するでしょう。
モッキングのためのベストプラクティスに関してこの記事を読むことをお勧めします。 > http://codebetter.com/JeremyMiller / 2006/01/10 /ベスト最悪のプラクティス - モックオブジェクト/
他人を偽りしないでください: http://aspiringcraftsman.com/2012/04/01 / TDDベストプラクティス - ドンタモックその他/
あなたの正確な状況を知らないが、とにかく私はこれを共有したいと思いました。