2010-12-02 34 views
0

Si j'ai ce testtest unitaire avec lambda fail en utilisant rhino maquette

Expect.Call(_session.Single<Admin>(x => x.Email == userModel.Email)).Repeat.Once().Return(null); 

me disant

Rhino.Mocks.Exceptions.ExpectationViolationException : ISession.Single (x => (x.Email == valeur (Enquete.Test.Controllers.MemberControllerTest + <> c__DisplayClassb) .userModel.Email)); Prévu # 1, Réel # 0.

Il échoue, mais si j'ajoute .IgnoreArguments() cela fonctionne. Est-il possible de tester en utilisant lambda? Si je débogue, je peux voir que mon Email est le même.

Voici le test complet:

[Test] 
     public void Register_Post_ReturnRedirectOnSuccess() 
     { 
      _builder.InitializeController(_controller); 

      var userModel = TestHelper.CreateMemberModel(); 
      var returnMemberRole = "Member"; 
      var tempPassword = "Val1dPass"; 
      var member = TestHelper.CreateMember(userModel); 
      var emailSubscription = "[email protected]"; 
      var subjectNotification = "sujet du meessaaggee"; 
      var mailUseSSL = "true"; 
      var message = userModel.FirstName + " " + userModel.LastName + " s'est inscrit au système d'enquête en ligne, veuillez confirmer son inscription."; 
      member.PasswordExpire = DateTime.Now.AddDays(-1); 
      member.Phone = userModel.Phone; 
      member.MemberNumber = userModel.MemberNumber; 
      member.PasswordExpire = DateTime.Now.AddDays(-1); 

      Expect.Call(_session.Single<Admin>(x => x.Email == userModel.Email)).Repeat.Once().Return(null); 
      Expect.Call(_session.Single<Member>(x => x.Email == userModel.Email)).Repeat.Once().IgnoreArguments().Return(null); 
      Expect.Call(_authService.GeneratePassword()).Repeat.Once().Return(tempPassword); 
      Expect.Call(_authService.MemberRole).Repeat.Once().Return(returnMemberRole); 
      Expect.Call(_authService.RegisterUser(userModel.Email, tempPassword, returnMemberRole)).Repeat.Once().Return(MembershipCreateStatus.Success); 
      _session.Add(member); 
      LastCall.Repeat.Once(); 
      _session.CommitChanges(); 
      LastCall.Repeat.Once(); 
      Expect.Call(_configHelper.GetValue("emailSubscription")).Repeat.Once().Return(emailSubscription); 
      Expect.Call(_configHelper.GetValue("subjectNotification")).Repeat.Once().Return(subjectNotification); 
      Expect.Call(_configHelper.GetValue("MailUseSSL")).Repeat.Once().Return(mailUseSSL); 
      _mailHelper.SendMail(emailSubscription, subjectNotification, message, Convert.ToBoolean(mailUseSSL)); 
      LastCall.Repeat.Once(); 

      _mock.ReplayAll(); 
      var result = _controller.Register(userModel); 

      _mock.VerifyAll(); 
      result.AssertActionRedirect().ToAction<MemberController>(c => c.RegisterSuccess()); 

     } 

Merci!

+0

Chaque fois que je vois quelqu'un qui utilise Rhino et qui a des problèmes, je vous suggère de consulter Moq par Daniel Cazullino (et d'autres). Cela peut ne pas résoudre votre problème, mais cela m'a aidé à nettoyer mes tests et m'a forcé à mieux apprendre le lambda. –

Répondre

1

Le lambda de votre test unitaire est compilé en une méthode au niveau de la classe (une méthode dans votre test unitaire). À l'intérieur de votre contrôleur, un lambda différent compile dans une méthode de niveau classe (à l'intérieur du contrôleur). Deux méthodes différentes sont utilisées pour que Rhino Mocks montre l'erreur d'attente. Plus ici: http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1

+0

Alors pensez-vous que l'option IgnoreArgument est une bonne approche? Avez-vous une autre solution? – VinnyG

+0

Je vérifierais que les données sont correctement définies après avoir appelé la méthode de votre contrôleur au lieu de définir des attentes sur des lambdas spécifiques - qui, comme vous le voyez, sont difficiles à vérifier pour l'égalité. – PatrickSteele

1

Malheureusement, les lambdas en C# utilisent l'égalité de référence, pas l'égalité des valeurs. Essayez ce qui suit:

Func<bool> f1 =() => true; 
Func<bool> f2 =() => true; 
Console.WriteLine("f1 == f2 results in " + (f1 == f2)); 

Devinez quoi? La réponse est fausse.

Il est aussi faux pour l'expression ...

Expression<Func<bool>> f1 =() => true; 
Expression<Func<bool>> f2 =() => true; 
Console.WriteLine(f1.ToString());   // Outputs "() => True" 
Console.WriteLine("a1 == a2 results in " + (f1 == f2)); // False 

Malheureusement, la meilleure façon de résoudre ce (et son laid) en C# (et donc Rhino Mocks) est d'utiliser ToString() sur les expressions et comparer les .

Expression<Func<bool>> f1 =() => true; 
Expression<Func<bool>> f2 =() => true; 
Console.WriteLine(f1.ToString());  // Outputs "() => True" 
Console.WriteLine("a1 == a2 results in " + (f1.ToString() == f2.ToString())); // True 

Vous devez être prudent avec cette technique comme deux expressions, « x => x » et « y => y », bien que fonctionnellement équivalent, sera toujours évaluée à faux en raison des différents paramètres. Sachez également que vous devez le faire avec Expression et non avec Func ou Action pour que cette astuce ToString() fonctionne.