2010-12-02 76 views
0

如果我有此測試單元測試失敗使用犀牛模擬

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

告訴我

Rhino.Mocks.Exceptions.ExpectationViolationException : ISession.Single(X =>( x.Email ==值(Enquete.Test.Controllers.MemberControllerTest + <> c__DisplayClassb).userModel.Email)); 預期#1,實際#0。

它失敗,但如果我添加.IgnoreArguments()它的作品。是否有可能使用lambda進行測試?如果我調試我可以看到我的電子郵件是相同的。

下面是完整的測試:

[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()); 

     } 

謝謝!

+0

每當我看到有人使用犀牛並遇到麻煩時,我建議您查閱Daniel Cazullino(和其他人)的Moq。它可能不是解決你的問題,但它幫助清理我的測試,並強迫我學習lambda表達式更好。 – 2010-12-02 22:37:32

回答

1

在單元測試拉姆達編譯成類級方法(單元測試內的方法)。在你的控制器內部,一個不同的lambda編譯成一個類級別的方法(在控制器內部)。使用兩種不同的方法,Rhino Mocks顯示期望錯誤。更多在這裏:http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1

+0

所以你認爲IgnoreArgument選項是一個好辦法?你有其他解決方案嗎? – VinnyG 2010-12-02 22:53:44

1

不幸的是在C#中使用的參考平等lambda表達式,而不是值相等。請嘗試以下操作:

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

猜猜是什麼?答案是錯誤的。

它也可用於表達假...

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 

不幸的是最好的方式來解決這個問題(和它醜陋的),在C#(因此犀牛嘲笑)是在表達式使用toString()和比較這些。

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 

你必須要小心這種技術,因爲兩個表達式,「X => X」和「Y => Y」,雖然在功能上等同,仍然會評估爲false,由於不同的參數。另外請注意,您必須對Expression執行此操作,而不是使用此ToString()技巧的Func或Action操作。