Why would I use AutoMapper?
- In order to implement better encapsulation and layering with less amount of coding
- In order to unit-test mapping code using a simple 'Mapper.AssertConfigurationIsValid()'
Passionate about developing software.
[Test]
public void CanValidateCreditCardNumber()
{
// Arrange
var viewMock = Isolate.Fake.Instance<ValidationView>();
var customerServiceMock = Isolate.Fake.Instance<CustomerService>();
var creditCardServiceMock = Isolate.Fake.Instance<CreditcardService>();
var customer56 = new Customer {CreditCardNr = "5500 0001 0001 0001"};
// Mock the (hidden) dependencies
Isolate.Swap.NextInstance<ValidationView>().With(viewMock);
Isolate.Swap.NextInstance<CustomerService>().With(customerServiceMock);
Isolate.Swap.NextInstance<CreditcardService>().With(creditCardServiceMock);
// Mock the calls to the dependencies
Isolate.WhenCalled(()=>viewMock.CustomerNr).WillReturn(56);
Isolate.WhenCalled(() => customerServiceMock.GetCustomer(56)).WillReturn(customer56);
Isolate.WhenCalled(()=> creditCardServiceMock.ValidateCreditCard("5500 0001 0001 0001")).WillReturn(true);
// Act
var presenter = new ValidationViewPresenter();
presenter.ValidateCreditCardOfCustomer();
// Assert
Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = true);
}
[Test]
public void CanValidateCreditCardNumber()
{
// Arrange
var viewMock = Isolate.Fake.Instance<ValidationView>();
var customerServiceMock = Isolate.Fake.Instance<CustomerService>();
var creditCardServiceMock = Isolate.Fake.Instance<CreditcardService>();
var customer56 = new Customer {CreditCardNr = "5500 0001 0001 0001"};
// Inject dependencies manually
var presenter = new ValidationViewPresenter(viewMock, customerServiceMock, creditCardServiceMock);
Isolate.WhenCalled(()=> viewMock.CustomerNr).WillReturn(56);
Isolate.WhenCalled(() => customerServiceMock.GetCustomer(56)).WillReturn(customer56);
Isolate.WhenCalled(() => creditCardServiceMock.ValidateCreditCard("5500 0001 0001 0001")).WillReturn(true);
// Act
presenter.ValidateCreditCardOfCustomer();
// Assert
Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = true);
}
[Test]
public void CanValidateCreditCardNumber()
{
// Arrange
var customer56 = new Customer {CreditCardNr = "5500 0001 0001 0001"};
var presenterMocker = new TypeMockAutoMocker<ValidationViewPresenter>(MockMode.AAA);
var viewMock = presenterMocker.Get<IValidationView>();
var customerServiceMock = presenterMocker.Get<ICustomerService>();
var creditCardServcieMock = presenterMocker.Get<ICreditCardService>();
Isolate.WhenCalled(() => viewMock.CustomerNr).WillReturn(56);
Isolate.WhenCalled(() => customerServiceMock.GetCustomer(56)).WillReturn(customer56);
Isolate.WhenCalled(() => creditCardServcieMock.ValidateCreditCard("5500 0001 0001 0001")).WillReturn(true);
// Act
presenterMocker.ClassUnderTest.ValidateCreditCardOfCustomer();
// Assert
Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = true);
}
As you can see the AutoMocking container couldn’t eliminate a lot of complexity. This is due to the fact that the test itself is complex and there are a number of non-default preconditions.[Test]
public void CanHandleNotExistingCustomer()
{
// Arrange
var presenterMocker = new TypeMockAutoMocker<ValidationViewPresenter>(MockMode.AAA);
var viewMock = presenterMocker.Get<IValidationView>();
Isolate.WhenCalled(() => viewMock.CustomerNr).WillReturn(56);
// Act
presenterMocker.ClassUnderTest.ValidateCreditCardOfCustomer();
// Assert
Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = false);
}
ConclusionSound’s like ‘convention over configuration’. And that makes life definitely easier.