新しいmvc3プロジェクトのコンセプトタイプコードの基本的な証明をしようとしています。RavenDBでMoqを使用しています。
アクション:
public ActionResult Index(string id)
{
var model = DocumentSession.Query<FinancialTransaction>()
.Where(f => f.ResponsibleBusinessId == id);
return View(model);
}
テスト:
private readonly Fixture _fixture = new Fixture();
[Test]
public void Index_Action_Returns_List_Of_FinancialTransactions_For_Business([Random(0, 50, 5)]int numberOfTransactionsToCreate)
{
// Arrange
var session = new Mock<IDocumentSession>();
var financialController = new FinancialController { DocumentSession = session.Object };
var businessId = _fixture.CreateAnonymous<string>();
var transactions = _fixture.Build<FinancialTransaction>()
.With(f => f.ResponsibleBusinessId, businessId)
.CreateMany(numberOfTransactionsToCreate);
// Mock
var ravenQueryableMock = new Mock<IRavenQueryable<FinancialTransaction>>();
ravenQueryableMock.Setup(x => x.GetEnumerator()).Returns(transactions.GetEnumerator);
ravenQueryableMock.Setup(x => x.Customize(It.IsAny<Action<Object>>()).GetEnumerator()).Returns(() => transactions.GetEnumerator());
session.Setup(s => s.Query<FinancialTransaction>()).Returns(ravenQueryableMock.Object).Verifiable();
// Act
var actual = financialController.Index(businessId) as ViewResult;
// Assert
Assert.IsNotNull(actual);
Assert.That(actual.Model, Is.InstanceOf<List<FinancialTransaction>>());
var result = actual.Model as List<FinancialTransaction>;
Assert.That(result.Count, Is.EqualTo(numberOfTransactionsToCreate));
session.VerifyAll();
}
問題は.Where(f => f.ResponsibleBusinessId == id)にあるように見えます。モックされたIRavenQueryableから、FinancialTransactionsのリストを返すので、.Where()はそれに基づいてフィルタリングすると思います。しかし、それはIQueryableなので、列挙するときに、式をすべて1つとして実行しようとしていると思います。
確認するために、アクションのクエリを次のように変更しました。
var model = DocumentSession.Query<FinancialTransaction>()
.ToList()
.Where(f => f.ResponsibleBusinessId == id);
これによりテストに合格できますが、すべてのレコードを列挙してからフィルタリングするため、理想的ではありません。
これでMoqを動作させる方法はありますか?