代码之家  ›  专栏  ›  技术社区  ›  Gavin Miller

模拟对象在单元测试中的正确应用

  •  1
  • Gavin Miller  · 技术社区  · 15 年前

    我有一个PresenterFactory,它基于角色参数创建Presenter类。具体来说,角色参数是一个我无法控制的外部类(即第三方)。

    我的工厂看起来像这样:

    public class PresenterFactory {
        public Presenter CreatePresenter(Role role, ...) {
            if (role.IsUserA("Manager")) {
                return new ManagerPresenter(...)
            }
            if (role.IsUserA("Employee")) {
                return new EmployeePresenter(...)
            }
        }
    }
    

    自从创建了 Role 对象强制数据库访问。我想我可以模仿这个物体。我的测试是这样的:

    public void TestPresenterFactory()
    {
        var mockRole = new Mock<Role>();
    
        mockRole .Setup(role=> role.IsUserA("Manager"))
            .Returns(true)
            .AtMostOnce();
    
        PresenterFactory.CreatePresenter(mockRole.Object, ...);
    
        mockUserInfo.VerifyAll();
    }
    

    但是我收到一个 ArguementException :

    不可重写成员上的设置无效:role=>role.isUsera(“manager”)。

    我不知道该去哪里,当然可以用一些课程修正。我做错什么了?

    4 回复  |  直到 15 年前
        1
  •  2
  •   womp    15 年前

    您可以为具有所有相同方法和属性但可模拟的角色创建包装对象,默认实现只返回基础角色的实现。

    然后,您的测试可以使用包装器角色来设置所需的行为。

    这通常是绕过真正需要模拟的具体类的一种方法。

        2
  •  0
  •   Doug R    15 年前

    您想要模拟的是创建一个角色对象,然后将该模拟对象传递到您的CreatePresenter方法中。在模拟上,您将设置确定它是哪种用户所需的任何属性。如果你 仍然 此时依赖于数据库,那么您可能会看到重构角色对象。

        3
  •  0
  •   Pavel Minaev    15 年前

    考虑使用一个模拟框架,它不会对代码的编写方式施加人为约束(例如,对要虚拟化的方法、不密封的类的要求等)。在.NET上下文中,我所知道的唯一这样的例子是typemock。

        4
  •  0
  •   Bostone    15 年前

    在Java中,当使用EasyMoCK扩展时,您将能够模拟“真实”的对象和方法,最可能的是可以用于您的目的的等效或替代的模拟框架。