Moq:设置一个方法,返回另一个方法的值

时间:2012-06-28 19:27:58

标签: mocking moq

我有一个测试,我在模拟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匹配第二个调用并返回我告诉它返回的值?

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

我明白了。我将第二个设置改为以下设置,现在可以正常工作。

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

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