【问题标题】:How to mock a controller that implements an interface如何模拟实现接口的控制器
【发布时间】:2013-07-19 23:10:47
【问题描述】:

所以我正在尝试测试此方法将返回“ManagerEventsIndex”的情况:

    public ActionResult Index()
    {
        if (this.CurrentUser != null)
        {
            if (this.CurrentUser.Role.Name == AvailableRoles.GameManager)
            {
                var model = new GameManagerEventsIndexModel();
                model.NumLocationsOfCurrentUser = this._customerLocationDataProvider.GetAllForUserId(CurrentUser.Id)
                                                                                    .Where(x => x.Active == true)
                                                                                    .Count();
                return View("ManagerEventsIndex", model);
            }
            else
            {
                return View();
            }
        }
        else
            return View("PublicIndex");
    }

但是这个控制器实现了另一个控制器 ApplicationController,如下所示:EventsController:ApplicationController,它是 Application 控制器中的 CurrentUser 对象,我需要模拟它来测试它......这是我到目前为止的测试方法。谢谢。

    [TestMethod]
    public void AssertGameManagerRoleReturnsGameManagerIndex()
    {
        // Arrange
        //eventsController = new EventsController(eventDataProvider.Object, playerEventDataProvider.Object, userDataProvider.Object,
                                                tokenAuthent.Object, dataContext.Object, customerLocationDataProvider.Object);

        var user = new Mock<User>();
        var role = new Mock<Role>();
        role.SetupSet(x => x.Name = "Ted");
        user.SetupSet(x => x.Role = role.Object);

        //?? var appController = new Mock<ApplicationController>();
        //?? appController.SetupSet(x => x.User = user);

        // var mController = new Mock<EventsController>();

        // Act
        var result = (ViewResult) eventsController.Index();

        // Assert
        Assert.AreEqual("ManagerEventsIndex", result.ViewName);
    }

【问题讨论】:

    标签: c# unit-testing asp.net-mvc-4 moq


    【解决方案1】:

    我认为您的问题是控制器类的实例中内置了太多功能,这使得测试变得更加困难。

    当您进行测试时,您希望确保不属于被测系统 (SUT) 的所有位都是可操作的。这使您可以调整所有其他位以生成场景。

    如果用户是你想要独立于控制器的东西,你有两个选择:

    • 使您想要 tweek 的对象可从外部访问(在这种情况下,将 User 设为公开)
    • 将您的用户与实际实现分离,并在构建时将 IUserService 或类似内容传递给类。

    这些将使您能够在测试中使用该对象。通常,当您遇到这样的问题时,事情有点难以测试,这是一个很好的指标,表明您没有正确模块化您的 SUT。

    【讨论】:

    • 嗯,所以没有办法制作一个模拟控制器,同时指定它应该实现的模拟接口?
    • @mapleafman 我不认为最小起订量支持这样的东西。您可以模拟整个界面或整个实例(不要将两者结合在一起)。我想我的意思是,如果你觉得你必须在测试中做一些疯狂的事情来产生一个场景,那通常是一种代码味道,这表明你可能没有以正确的方式分解实际的 SUT
    • 谢谢,我很感激,我同意,只是和其他人一起工作,这主要是他们的设计,只是想看看是否有什么可以做的,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    相关资源
    最近更新 更多