「サービスレイヤー」/「アプリケーションファサードレイヤー」メソッドの単体テストを試みています。これは私が単体テストしようとしている方法です:
// Create a new order in the database for a customer. Given a customer id,
// will create a new order and return an OrderDto for use in the presentation
// layer.
public OrderDto CreateOrderForCustomer(int customerId)
{
// Find the customer
var customer = _customerRepository.GetCustomerById(customerId);
// Create an order and apply special logic to get it ready for use.
var orderFactory = new OrderFactory();
var order = orderFactory.CreateOrder(customer);
// IMPORTANT: This is what I'm trying to unit test ...
_orderRepository.Save(order);
order.Status = "Editing";
// Using AutoMapper to turn this into a DTO that will be returned
// to the Presentation layer. The Mappings are created in the
// constructor and not depicted in this code snippet.
var orderDto = Mapper.Map<Order, OrderDto>(order);
return orderDto;
}
(注...わかりやすくするために、ここに大量のメモを追加しました。通常、私はそれほどおしゃべりではありません。)
このメソッドの仕事は、ドメイン レイヤー メソッドとパーシスタンス レイヤー メソッドを調整して空の注文を作成し、それを永続化し、単純な DTO として返すことなので、これは FakeItEasy にとって素晴らしい仕事だと思いました...それらを確認します重要なメソッドは、FakeItEasy の MustHaveHappened() を使用して確実に呼び出されるように適切に編成されています。
それを念頭に置いて、私が作成した単体テストは次のとおりです。
[TestMethod]
public void CreateOrderForCustomer_ValidCustomer_CreatesNewOrder()
{
// Arrange
var customer = _customerRepository.GetCustomerById(1);
Assert.AreEqual(0, customer.Orders.Count);
// Act
var orderDto = _orderEntryService.CreateOrderForCustomer(1);
// Assert
// Here I'm trying to make sure to re-create the order that was actually
// sent into the _customerRepository.Save() ... I should be able to
// simple un-map the OrderDto back to an Order, and undo the property
// change.
var order = Mapper.Map<OrderDto, Order>(orderDto);
order.Status = "New";
A.CallTo(() => _customerRepository.GetCustomerById(1)).MustHaveHappened();
// **THIS CAUSES AN EXCEPTION**
A.CallTo(() => _orderRepository.Save(order)).MustHaveHappened();
Assert.AreEqual(1, customer.Orders.Count);
}
単体テストでは、テスト中のメソッドで作成された実際の注文にアクセスできません。次善の策を試してみました...テスト中のメソッドによって返された注文の DTO バージョンを取得し、マップしますOrder の DTO バージョンをドメイン モデル Order の新しいインスタンスに戻し、FakeItEasy の MustHaveHappened() に送信する前にプロパティが同じであることを確認します。
単体テストをデバッグし、実際の注文のプロパティと FAKED の注文のプロパティを比較しました...確かに、それらは同一です。また、デバッグを通じて、_customerRepository.Save(order) が実際に呼び出されていることを確認できます。
質問 .MustHaveHappened() が失敗するのは、本質的に Order オブジェクトの 2 つの異なるインスタンスを送信しているためです。それらのプロパティは同じですが? プロパティは同じですが、FakeItEasy は、メソッド呼び出しが行われたことを確認するために入力パラメーターの同じインスタンスを必要としますか?
さらに、この種のものをどのようにテストする必要があるかについての提案 (つまり、オーケストレーション/サービス/「アプリケーション ファサード」/レイヤー メソッドと呼びたいもの) はありますか?