1

我有一个测试,我正在模拟在控制器中调用的 2 个服务调用。第一次调用(用户 POCO)的返回值用于调用第二次。问题是它似乎与第二个不匹配,因为它一直返回 null。如果我将服务更改为返回字符串而不是 User 对象,则它可以正常工作。

测试:

        [Test]
    public void GivenExternalReturnUrl_ReturnsHomePage()
    {
        var model = new Login
        {
            Username = "user1",
            Password = "password1",
            ReturnUrl = "http://google.com"
        };
        UserService.Setup(x => x.ValidateUser(model.Username, model.Password)).Returns(User);
        var cookie = new HttpCookie("test");
        UserService.Setup(x => x.BuildLoginCookie(User, model.RememberMe)).Returns(cookie);

        var result = Controller.Login(model) as RedirectToRouteResult;
        result.Should().Not.Be.Null();
        result.RouteValues["controller"].Should().Equal("Home");
        result.RouteValues["action"].Should().Equal("Index");
        UserService.Verify(x => x.BuildLoginCookie(User, model.RememberMe), Times.Once());
    }

BuildLoginCookie 返回 null 而不是 cookie 对象。

它正在测试的操作:

        [HttpPost]
    public ActionResult Login(Login model)
    {
        if (ModelState.IsValid)
        {
            var user = _userService.ValidateUser(model.Username, model.Password);
            if (user != null)
            {
                var cookie = _userService.BuildLoginCookie(user, model.RememberMe);
                Response.Cookies.Add(cookie);

                if (Url.IsLocalUrl(model.ReturnUrl))
                    return Redirect(model.ReturnUrl);
                return RedirectToAction("Index", "Home");
            }
            ModelState.AddModelError("InvalidCredentials", "The user name or password provided is incorrect.");
        }

        // If we got this far, something failed, redisplay form
        model.Password = null;  //clear the password so they have to re-enter it
        return View(model);
    }

我需要做什么才能使 Moq 匹配第二次调用并返回我告诉它返回的值?

4

2 回答 2

1

问题出在你的财产上public UserWithRolesPermissions User { get { new UserWithRolesPermissions(); } }

每次调用它时,它都会创建一个新实例,因此对它的两个引用各自接收一个新实例,它们不相等。因此,对 setup 的调用将与调用不匹配。

如果您将代码更改为使用单个实例,它应该可以正常工作。

var user = new UserWithRolesPermissions();
UserService.Setup(x => x.ValidateUser(model.Username, model.Password)).Returns(user);
var cookie = new HttpCookie("test");
UserService.Setup(x => x.BuildLoginCookie(user, model.RememberMe)).Returns(cookie);

另一种选择是避免对实例进行比较,而只匹配一个属性。

UserService.Setup(x => x.BuildLoginCookie(It.Is<User>(u => u.Username == model.Username), model.RememberMe)).Returns(cookie);
于 2012-06-28T19:51:07.433 回答
0

我想到了。我将第二个设置更改为以下设置,它现在可以工作了。

UserService.Setup(x => x.BuildLoginCookie(It.Is<UserWithRolesPermissions>(u => u.Username == User.Username), model.RememberMe)).Returns(cookie);

它一定很难匹配自定义类对象或其他东西。

于 2012-06-28T19:50:31.063 回答