"서비스 레이어"/ "어플리케이션 외관 레이어"메소드를 테스트하려고합니다.FakeItEasy는 MustHaveHappened가 발생하지 않았다고 말합니다.하지만 그랬습니다.
// 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;
}
(.. 나는 명확성을 위해 여기에 풍부한 메모를 추가했습니다 ... 참고 나는 보통이 수다스러운 아니에요)
이 방법의 가입일 : 이것은 단위 테스트에 내가 노력하고있어 방법 직업은 Domain Layer 메소드와 Persistence Layer 메소드를 조종하여 빈 주문을 작성하고이를 유지 한 다음 간단한 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);
}
단위 테스트에서, 나는 시험 방법에서 생성 된 실제 주문에 액세스 할 수 없습니다, 나는 시도 다음으로 최선을 다하십시오 ... 테스트중인 메소드에 의해 반환 된 Order의 DTO 버전을 가져오고 Order의 DTO 버전을 도메인 모델 Order의 새 인스턴스로 다시 매핑하고 속성이 동일한 지 확인하십시오 FakeItEasy의 MustHaveHappened()에게 보내기 전에.
단위 테스트를 디버깅하고 실제 주문 속성과 FAKED 주문 속성을 비교해 보았습니다 ... 동일하다는 점을 확신합니다. 또한 디버깅을 통해 _customerRepository.Save (order)가 실제로 호출되고 있음을 확인할 수 있습니다.
질문 이 (.MustHaveHappened되어) 나는 기본적으로 주문 개체의 두 가지 경우에 보낸다 때문에 실패 - 그 속성이 동일하더라도? 프로퍼티는 같지만, FakeItEasy는 메소드 호출이 발생했는지 확인하기 위해 입력 매개 변수의 동일한 인스턴스가 필요합니까?
또한 이런 종류의 테스트 (예 : 오케스트레이션/서비스/"애플리케이션 외관"/ what-ever-you-want-to-call-it 레이어 방법)에 대한 제안 사항은 무엇입니까?
감사합니다. 감사합니다. 감사합니다. 특히 OrderFactory에 관한 훌륭한 팁! –
참조 비교가 사용되는 것은 아니며 Equals 구현이 사용된다는 것입니다. 그래서 Equals-method를 오버라이드하여 동등한 명령을 동등하다고 생각하면 문제도 해결할 수 있습니다. –
@ PatrikHägne : 예, 정신 지름길이 지나치게 달려있어 알림을 보내 주셔서 감사합니다. –