使用 rhino 模拟进行 lambda 单元测试失败
如果我有这个测试
Expect.Call(_session.Single<Admin>(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 = "[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());
}
谢谢!
If I have this test
Expect.Call(_session.Single<Admin>(x => x.Email == userModel.Email)).Repeat.Once().Return(null);
Telling me
Rhino.Mocks.Exceptions.ExpectationViolationException
:
ISession.Single(x
=> (x.Email == value(Enquete.Test.Controllers.MemberControllerTest+<>c__DisplayClassb).userModel.Email));
Expected #1, Actual #0.
It fails but if I add .IgnoreArguments() it works. Is it possible to test using lambda? If I debug I can see that my Email is the same.
Here's the full test :
[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());
}
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
单元测试中的 lambda 编译为类级方法(单元测试中的方法)。在控制器内部,不同的 lambda 编译为类级方法(在控制器内部)。使用两种不同的方法,因此 Rhino Mocks 显示期望错误。更多信息请参见:http://groups.google.com/group/ rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1
The lambda in your unit test compiles into a class-level method (a method inside your unit test). Inside your controller, a different lambda compiles into a class-level method (inside the controller). Two different methods are used so Rhino Mocks shows the expectation error. More here: http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1
不幸的是,C# 中的 lambda 使用引用相等,而不是值相等。尝试以下操作:
你猜怎么着?答案是错误的。
对于表达式来说也是错误的...
不幸的是,在 C#(以及 Rhino Mocks)中解决这个问题(及其丑陋)的最佳方法是在表达式上使用 ToString() 并比较它们。
您必须小心使用此技术,因为两个表达式“x => x”和“y => y”虽然在功能上等效,但由于参数不同,仍然会计算为 false。另请注意,您必须使用 Expression 而不是 Func 或 Action 来执行此操作,这样 ToString() 技巧才能起作用。
Unfortunately lambdas in C# use reference equality, not value equality. Try the following:
Guess what? The answer is False.
It's also false for Expression...
Unfortunately the best way to solve this (and its ugly) in C# (and therefore Rhino Mocks) is to use ToString() on Expressions and compare those.
You have to be careful with this technique as two Expressions, "x => x" and "y => y", although equivalent functionally, will still evaluate to false due to the different parameters. Also be aware that you must do this with Expression and not Func or Action for this ToString() trick to work.