【问题标题】:Use Moq to mock Constructor?使用 Moq 模拟构造函数?
【发布时间】:2011-02-27 21:28:20
【问题描述】:

我有这么一组构造函数:

public BusinessObjectContext()
         : this(CloudStorageAccount.FromConfigurationSetting("DataConnectionString").TableEndpoint.ToString(),
                CloudStorageAccount.FromConfigurationSetting("DataConnectionString").Credentials) {}

public BusinessObjectContext(string dataConnectionString)
         : this(CloudStorageAccount.Parse(dataConnectionString).TableEndpoint.ToString(),
                CloudStorageAccount.Parse(dataConnectionString).Credentials) { }

public BusinessObjectContext(String baseAddress, StorageCredentials credentials) 
         : base(baseAddress, credentials) { } 

但是,在测试/模拟时,我需要没有任何连接字符串参数的对象。我怎样才能做到这一点 - 最好在起订量中?

这可能吗?

【问题讨论】:

    标签: c# .net unit-testing constructor moq


    【解决方案1】:
    var myMockBOC = new Mock<BusinessObjectContext>(null, null);
    

    这将为您的两个参数传入空值。

    另一种方法是创建一个仅供测试使用的内部构造函数,并使用InternalsVisibleTo 允许您的测试程序集使用它。不幸的是,这有一个很大的缺点,如果你签署你的程序集,Moq is unable to use the constructor。不过,这应该在 4.0 版本的 Moq 中得到解决。

    【讨论】:

    • 内部构造函数的缺点是现在您正在编写代码来支持您的单元测试。
    • 我认为,当有目的要求 public API 不可注入时,这是可以接受的。唯一会出现问题的情况是,如果您的构造函数不简单,并且包含业务逻辑 - 那么,俗话说,您将遇到两个问题......
    • 非常简单的解决方案!帮了我很多!
    • 如果类被密封,我不确定这会起作用
    【解决方案2】:

    听起来好像你有一种代码味道 - constructor is doing too much work。本文包含一组针对此类情况的修复程序。基本上答案是在构造函数中执行赋值,而不是执行业务逻辑。

    【讨论】:

    • Hrrm。我看到了这个概念中的论点。另一方面,我想阻止 GenericBusinessObject 对象的用户考虑数据源上下文。如果我遵循您的论点,那么 GenericBusinessObject 的用户必须考虑它。这是较少的抽象。也许没有别的办法,但有些事情让我犹豫了。
    • 制作工厂或使用 IOC 容器来消除用户担心数据上下文的需要。
    【解决方案3】:

    如果您不想使用构造函数参数,则可以在模拟它时使用 It.IsAny() 方法传递。它会将空值传递给它。当你使用这种方法而不是写 null 时,它会更具可读性。

    【讨论】:

      猜你喜欢
      • 2011-03-17
      • 2011-11-16
      • 2017-11-04
      • 1970-01-01
      • 2013-11-17
      • 1970-01-01
      • 2014-06-03
      • 2013-01-21
      • 2013-01-12
      相关资源
      最近更新 更多