使用rhino mock进行lambdaunit testing失败

如果我有这个测试

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

告诉我

Rhino.Mocks.Exceptions.ExpectationViolationException:ISession.Single(x =>(x.Email == value(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 = "subscription@corpiq.com"; 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(x => x.Email == userModel.Email)).Repeat.Once().Return(null); Expect.Call(_session.Single(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(c => c.RegisterSuccess()); } 

谢谢!

unit testing中的lambda编译为类级方法(unit testing中的方法)。 在你的控制器中,一个不同的lambda编译成一个类级方法(在控制器内部)。 使用了两种不同的方法,因此Rhino Mocks显示了期望误差。 更多信息: http : //groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc = 1

不幸的是,C#中的lambdas使用引用相等,而不是值相等。 请尝试以下方法:

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

你猜怎么着? 答案是假的。

表达式也是错误的……

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

不幸的是,在C#(以及Rhino Mocks)中解决这个问题(以及它的丑陋)的最好方法是在表达式上使用ToString()并比较它们。

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

您必须小心使用此技术,因为两个表达式“x => x”和“y => y”虽然function相同,但由于参数不同,仍会评估为false。 另外请注意,必须使用Expression而不是Func或Action才能使用此ToString()技巧。