【问题标题】:Proper application of Mock objects in Unit Testing在单元测试中正确应用 Mock 对象
【发布时间】:2009-07-14 22:47:31
【问题描述】:

我有一个 PresenterFactory,它基于 Role 参数创建 Presenter 类。具体来说,Role 参数是我无法控制的外部类(IE 3rd 方。)

我的工厂看起来像这样:

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

我不确定去哪里,当然可以使用一些路线修正。我做错了什么?

【问题讨论】:

    标签: unit-testing mocking moq


    【解决方案1】:

    您可以为 Role 创建一个包装对象,该对象具有所有相同的方法和属性,但可模拟,并且默认实现仅返回底层 Role 的实现。

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

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

    【讨论】:

      【解决方案2】:

      您要模拟的是创建一个 Role 对象,然后将该模拟对象传递给您的 CreatePresenter 方法。在模拟中,您可以设置确定用户类型所需的任何属性。如果此时您仍然依赖于数据库,那么您可能会考虑重构您的 Role 对象。

      【讨论】:

      • 这就是我尝试过的,但是得到了一个在不可覆盖的成员上设置无效异常
      • 在这种情况下,我建议 womp 的回答是围绕 Role 对象编写一个包装类。
      【解决方案3】:

      考虑使用一个模拟框架,该框架不会对必须如何编写可模拟的代码施加人为约束(例如要求虚拟方法、不密封类等)。我在 .NET 上下文中知道的唯一示例是 TypeMock。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2010-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多