Try fast search NHibernate

08 March 2010

AAA with Moq and Sharp Tests Ex

Log time ago I have added an issue to Moq’s issue-tracker (the issue here) and today I will show you why it can be closed.

In your application you have some places where a class is “working as a bridge” between two others. this is a common situation in MVP (Model View Presenter) and in MVC (Model View Controller).

To test “the bridge” in many case you want mock the others two classes (note: the test is needed even when you are using a Object2Object auto-mapper).

In pure AAA style the test may look as this (I have simplified it):

[TestMethod]
public void WhenPresentCallServiceRegisterThenValuesAreMappedFromView()
{
var view = new Mock<IUsuarioParticularNuevoView>();
var service = new Mock<IUsuarioParticularNuevoService>();

view.SetupGet(v => v.Contraseña).Returns("pizza");
view.SetupGet(v => v.AceptaTermino).Returns(true);
view.SetupGet(v => v.Apellido).Returns("Fulano");
view.SetupGet(v => v.CiudadSelecionadaId).Returns(100);
view.SetupGet(v => v.CodigoPostal).Returns("AC123");
view.SetupGet(v => v.Email).Returns("pizzaCALDA");
view.SetupGet(v => v.EsHombre).Returns(false);
view.SetupGet(v => v.FechaNacimiento).Returns(DateTime.Today);
view.SetupGet(v => v.Nombre).Returns("Mengano");
view.SetupGet(v => v.OrigenReferencia).Returns("Amigo");
view.SetupGet(v => v.ProvinciaSelecionadaId).Returns(123);
view.SetupGet(v => v.RecibeNoticias).Returns(false);
view.SetupGet(v => v.TelefonoArea).Returns("011");
view.SetupGet(v => v.TelefonoNumero).Returns("123456");
view.SetupGet(v => v.OrigenRegistracion).Returns("yahoo");

var pre = new UsuarioParticularNuevoPresenter(view.Object, service.Object);
pre.Register();

service.Verify(
s =>
s.Register(
It.Is<UsuarioNuevoInfo>(
uni =>
uni.AceptaTermino && uni.Apellido == "Fulano" && uni.CiudadSelecionadaId == 100 && uni.CodigoPostal == "AC123"
&& uni.Contraseña == "pizza" && uni.Email == "pizzacalda" && uni.EsHombre == false
&& uni.FechaNacimiento == DateTime.Today && uni.Nombre == "Mengano" && uni.OrigenReferencia == "Amigo"
&& uni.ProvinciaSelecionadaId == 123 && uni.RecibeNoticias == false && uni.TelefonoArea == "011"
&& uni.TelefonoNumero == "123456" && uni.OrigenRegistracion == "yahoo")));
}

I know that I have two bugs in the implementation of the class UsuarioParticularNuevoPresenter but how can I know which are if the failure message is this:

Test method MoqSharpTestsEx.ShowTest.WhenPresentCallServiceRegisterThenValuesAreMappedFromView threw exception: Moq.MockException:
Expected invocation on the mock at least once, but was never performed: s => s.Register(It.Is<UsuarioNuevoInfo>(uni => ((((((((((((((uni.AceptaTermino && (uni.Apellido = "Fulano")) && (uni.CiudadSelecionadaId = 100)) && (uni.CodigoPostal = "AC123")) && (uni.Contraseña = "pizza")) && (uni.Email = "pizzacalda")) && (uni.EsHombre = False)) && (uni.FechaNacimiento = DateTime.Today)) && (uni.Nombre = "Mengano")) && (uni.OrigenReferencia = "Amigo")) && (uni.ProvinciaSelecionadaId = 123)) && (uni.RecibeNoticias = False)) && (uni.TelefonoArea = "011")) && (uni.TelefonoNumero = "123456")) && (uni.OrigenRegistracion = "yahoo")))).

If you are following my blog you know that there is something new in the .NET ecosystem : Sharp Tests Ex and its Satisfier.

What I need to do, to have a more readable failure message, is really simple:

service.Verify(
s =>
s.Register(
It.Is<UsuarioNuevoInfo>(
ui =>
ui.Satisfy(
uni =>
uni.AceptaTermino && uni.Apellido == "Fulano" && uni.CiudadSelecionadaId == 100 && uni.CodigoPostal == "AC123"
&& uni.Contraseña == "pizza" && uni.Email == "pizzacalda" && uni.EsHombre == false
&& uni.FechaNacimiento == DateTime.Today && uni.Nombre == "Mengano" && uni.OrigenReferencia == "Amigo"
&& uni.ProvinciaSelecionadaId == 123 && uni.RecibeNoticias == false && uni.TelefonoArea == "011"
&& uni.TelefonoNumero == "123456" && uni.OrigenRegistracion == "yahoo"))));

Can you see the difference ?
Well does no matter… you will see the difference in the failure message :

MoqSharpTestsEx.UsuarioNuevoInfo Should Satisfy (uni => uni.Email == "pizzacalda")
Strings differ at position 6.
pizzaCALDA
pizzacalda
_____^____

And

MoqSharpTestsEx.UsuarioNuevoInfo Should Satisfy (uni => uni.EsHombre == False)

I’m going to say that issue can be closed because I’m a Sharp Tests Ex user.

Are you satisfying your tests ?

4 comments:

  1. Failing XUnit tests using your extensions seem to crah Resharper 4.5. Have you seen this too?

    ReplyDelete
  2. Which xUnit test runner are you using ? and which SharpTestsEx dll ?
    btw I'm using Resharper 5 and the place for issues is this http://sharptestex.codeplex.com/WorkItem/List.aspx

    Thanks for your issue.

    ReplyDelete
  3. Jan,
    we have tested SharpTestsEx with TD.NET and with this conf. for ReSharper:
    ReSharper4.5, xUnit1.5, xUnitContrib 0.31 ( plugin)
    There was no issues.

    ReplyDelete
  4. Hi Fabio,

    anything further, I'll move to the issue tracker, just as a heads up, this is happening at 2 completely different computers (coworker and mine) with exactly this setup/versions.

    Thanks for looking into it!

    ReplyDelete