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.
Following this rules we had some sort of guidelines about where to locate the business-logic and when to implement a repository. I think it was worth to have the aggregates. It was a valuable concept when we had to change our application from a 2-tier to a 3-tier architecture.
Nevertheless we always had following problems with aggregates:
Why is our business-logic in the zone of pain?
We generally get closer to the 'zone of pain' (see link for details), when a high number of types in an assembly:
Since I can't see any value in implementing business-logic abstract (1.) and our business-logic already depends on a small number of types in other assemblies (2.) the only variable would be to reduce the number of types that are used by other assemblies (3.).
How could we do it different?
We could try to better encapsulate the internals of an aggregate avoiding the problems described above. That means, not allowing to access any internals by another type than the aggregate root. This increases the afferent coupling of the aggregate root, on the other hand eliminates the afferent coupling of the internals. The afferent coupling of the business logic assembly itself would then decrease.
Therefore I transformed one of our aggregates from something like that
// File Invoice.cs
public class Invoice
{
public EntitySet<InvoicePosition> Positions { get; set; }
}
public class InvoicePosition
{
}
// File Invoice.cs
public partial class Invoice
{
private EntitySet<Invoice.InvoicePosition> Positions { get; set; }
}
// File InvoicePosition.cs
public partial class Invoice
{
private class InvoicePosition
{
}
}
After completing the refactoring and changing some logic in the presentation layer I got the following code metrics:Testability and Unittests
As the internals are completely hidden from outside now I test the refactored aggregate with state-based black-box tests. I think that's a reasonable way to do it since the test setup do not depend anymore on the implementation details of an aggregate. I'm not sure if this should be a general testing strategy for aggregates. I think there are more complex cases, where white-box tests would still be needed. The following pictures shows on the left, the test-code before the refactoring and on the right, the test-code after:protected IView _view;
protected Presenter _presenter;
protected EventHandler _updateRequestedEvent;
protected IServiceGateway _serviceGatway;
The setup of the this objects is not showed here. It simples instantiates mocks for the View and the ServiceGateway and injects it into the Presenter using Constructor-Injection. The _updateRequestedEvent is a mocked event on the view and is also used later in the example.
First I have to specify a story. This is done like that:
[TestFixtureSetUp]
public void FixtureSetup()
{
_getCurrentTimeStory = new Story("Getting the current service time");
_getCurrentTimeStory.AsA("User").IWant("to update the displayed current time")
.SoThat("I can see what time is on the serivce side");
}
And that's one scenario that came in my mind:
[Test]
public void HelloNTServiceIsNotAvailable()
{
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
_view.ShowMessageBox("The Service is currently not available");
recorder.CheckArguments();
}
_getCurrentTimeStory.WithScenario("Service is not available")
.Given("the Service returns an exception", new Exception("Error"), e =>
{
using (RecordExpectations recorder = RecorderManager.StartRecording))
{
recorder.ExpectAndThrow(_serviceGatway.GetTime(), e);
}
})
.When("I update the current time", () => _updateRequestedEvent(this, EventArgs.Empty))
.Then("a message box should display", "The Service is currently not available", m =>
{
MockManager.Verify();
})
;
}
Looks quite chaotic and a developer not used to NUnit,TypeMock and NBehave might not understand it at first glance. I also think the combination of NUnit,TypeMock and NBehave is a little bit strange as they do not integrate very well. Maybe there is another way how to combine those frameworks?
But what I like is the overall structure that it gives to the tests and the readable test output that can be interpreted by a product owner. Here are now the scenario above and another scenario that I could present to him:
Story: Getting the current service time
Narrative:
As a User
I want to update the displayed current time
So that I can see what time is on the serivce side
Scenario 1: Service is not available
Given the Service returns an exception: System.Exception: Error
When I update the current time
Then a message box should display: The Service is currently not available
Scenario 2: Service is available
Given the Service returns the time: 01.01.2000 12:24:23
When I update the current time
Then the label on the view should display: 12:24
Introducing a DI-Framework
One trying to write tests in such an environment knows that integrating the real wpf- and wcf-environment into the tests is a bad idea. Instead it's better to stub and mock those environments to get easier, more stable, and faster tests. This means we usually want a test-configuration where the most external dependencies (like wpf or wcf) are mocks or stubs. On the other hand we want to have a configuration on a deployed system that utilizes the real dependencies. So it's something about configuration and that's where the DI-frameworks come into play.
I decided to give Jeremy's StructureMap a try because it doesn't look so overloaded like Sprint.NET or Windsor.
Following code shows my wcf-service IService that I include in the presentation-layer as a Service-Gateway (see also ServiceStub-Pattern):
[ServiceContract]
public interface IService
{
[OperationContract]
DateTime GetTime();
}
/// <summary>
/// Gateway to intercept for testing
/// </summary>
public interface IServiceGateway : IService
{
void Close();
}
/// <summary>
/// Real gateway using the wcf generated ServiceClient class
/// </summary>
public class ServiceGateway : IServiceGateway
{
private readonly ServiceClient _service;
public ServiceGateway()
{
_service = new ServiceClient();
}
public void Close()
{
_service.Close();
}
public DateTime GetTime()
{
return _service.GetTime();
}
}
/// <summary>
/// Stub for testing
/// </summary>
public class ServiceGatewayStub : IServiceGateway
{
public void Close()
{
}
public DateTime GetTime()
{
return new DateTime(2000, 1, 1, 12, 34, 55, 12);
}
}
Step 1:IServiceGateway gateway = ObjectFactory.GetInstance<IServiceGateway>()
and using the following configuration for the tests<StructureMap>
<DefaultInstance PluginType="HelloNTPresentation.IServiceGateway,HelloNTPresentation" PluggedType="HelloNTService.ServiceGatewayStub,HelloNTTests" Scope="Singleton"/>
</StructureMap>
I could wire the code during the tests to the ServiceGatewayStub instead of the real ServiceGateway.<StructureMap>
<DefaultInstance PluginType="HelloNTPresentation.IServiceGateway,HelloNTPresentation" PluggedType="HelloNTPresentation.ServiceGateway,HelloNTPresentation" Scope="Singleton"/>
</StructureMap>
After I have had read how to build an IoC container in 15 lines of code I thought that DI can't be so difficult and I tried to build my own DI-framework. I liked very much that I could configure the DI in the code now and eliminate the file-based configuration: ObjectFactory.Register<IServiceGateway>(() => new ServiceGatewayStub());
IServiceGateway gateway = ObjectFactory.Create<IServiceGateway>();
All tests were green and I was happy to start the refactored sample application first time after. But there was big surprise when it crashed. I had forgotten to configure DI for the wcf-service and wpf-service. But where should I put that configuration? Both of them run in some kind of hosted environment and I wasn't able to find a nice place to put that configuration-code. So I realized that it's a little bit harder than I thought to write an own DI-Framework. [ServiceContract]
public interface IService
{
[OperationContract]
DateTime GetTime();
}
[PluginFamily("ServiceGateway")]
public interface IServiceGateway : IService
{
}
[Pluggable("ServiceGateway")]
public class ServiceGateway : IServiceGateway
{
}
Step 4: public class Presenter: IDisposable
{
readonly IView _view;
readonly IServiceGateway _service;
public Presenter(IView view, IServiceGateway service)
{
_view = view;
_service = service;
}
}
That presenter shows all internal dependencies on its constructor. This enables us to use constructor injection when writing tests with a Mock-Framework (e.g. TypeMock) _serviceGatway = RecorderManager.CreateMockedObject<IServiceGateway>();
_view = RecorderManager.CreateMockedObject<IView>();
_presenter = new Presenter(_view, _serviceGatway);
But what's about the others that don't want to bother about providing those dependencies to the constructor? And that's where the DI-framework gets really valueable because it enables us to instantiate concrete classes without providing the needed arguments to the constructor. Following code is from the wpf-client and shows how this is done: Presenter presenter = ObjectFactory.FillDependencies<Presenter>();
Just for completeness, I have to mention how I configured IView: [PluginFamily("Window1")]
public interface IView
{
}
[Pluggable("Window1")]
public partial class Window1 : Window, IView
{
}
SummarySounds interesting .... So I bought yesterday something about WPF to update myself with 'state of the art rich client development'.
Maybe the new Microsoft Synch Framework could be interesting in that context too. I watched this and it looks promising. I have to admit that I hate that kind of presentations but it looks that it's flexible and can be extended. I'm not yet sure about that but at least the synch-runtime can be instantiated in a object-oriented manner and that's always a good sign. Would be great if it could be connected to a service instead of a database.
Ich werde also in Zukunft das letzte '=>' als 'becomes' und alle vorangehenden '=>' als 'goes to' aussprechen.
Beispiele: