使用 rhino 模拟进行 lambda 单元测试失败

发布于 2024-10-06 01:58:06 字数 3011 浏览 2 评论 0原文

如果我有这个测试

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小女人ら 2024-10-13 01:58:06

单元测试中的 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

寂寞陪衬 2024-10-13 01:58:06

不幸的是,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#(以及 Rhino Mocks)中解决这个问题(及其丑陋)的最佳方法是在表达式上使用 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 而不是 Func 或 Action 来执行此操作,这样 ToString() 技巧才能起作用。

Unfortunately lambdas in C# use reference equality, not value equality. Try the following:

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

Guess what? The answer is False.

It's also false for 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

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.

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文