I'm trying to unit test a "service layer" / "application facade layer" method. This is the method I'm trying to unit test:
// 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
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 ...
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);
public void CreateOrderForCustomer_ValidCustomer_CreatesNewOrder()
var customer = _customerRepository.GetCustomerById(1);
var orderDto = _orderEntryService.CreateOrderForCustomer(1);
// 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
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();
Is .MustHaveHappened() failing because I'm essentially sending in two different instances of the Order object -- even though their properties are identical?
Yes. FakeItEasy will use
.Equals, which (unless your class overrides it) for reference types defaults to reference equality.
(...) does FakeItEasy need the same instance of the input parameter to ensure that the method call has happened?
No. You can do custom argument matching like this:
A.CallTo(() => _orderRepository.Save(A<Order>.That.Matches(o => o.Status == "New" && o.Id == 10 ))).MustHaveHappened();
But, this problem revealed an issue with your code. From your sample it's clear you're injecting
_customerRepository as a dependency. That's great. Why don't you do the same with
OrderFactory? If it were injected via interface/base class dependency, you could then easily mock (fake) it and your current problem wouldn't exist.
If you can alter your code I'd suggest injecting the factory (following simple guideline - "no
news is good news!"). If not, use custom matchers to verify order properties like I did in the sample above.