【问题标题】:Mocking objects without no-argument constructor in C# / .NET在 C# / .NET 中模拟没有无参数构造函数的对象
【发布时间】:2011-03-11 02:44:23
【问题描述】:

是否可以从不提供无参数构造函数并且不将任何参数传递给构造函数的类创建模拟?也许动态创建 IL?

背景是我不想只为测试定义接口。解决方法是为测试提供无参数构造函数。

【问题讨论】:

  • 另外,从创建 Mocks 的 Moq 用法来看,您需要将方法设为虚拟。似乎在那种情况下,界面通常会更好。不确定其他 Mocking 框架。
  • 理想情况下,应该在整个代码中使用接口;与具体实现相比,因此“仅为测试创建接口”的评论成为一个有争议的观点。
  • 我认为只有一个实现的接口是毫无价值的人工制品。
  • 你会发现在c#中测试的时候必须要创建一个接口。作为替代方案,您可以为方法/属性提供 virtual 关键字,但您会发现接口可以更好地表达您的设计,并允许将具体实例与消费者更好地解耦。

标签: c# .net reflection constructor mocking


【解决方案1】:

当然。在这个例子中,我将使用 Moq,一个非常棒的模拟库。

例子:

public class MyObject
{
     public MyObject(object A, object B, object C)
     {
          // Assign your dependencies to whatever
     }
}

Mock<MyObject> mockObject = new Mock<MyObject>();
Mock<MyObject> mockObject = new Mock<MyObject>(null, null, null); // Pass Nulls to specific constructor arguments, or 0 if int, etc

但在许多情况下,我将 Mock 对象分配为参数,以便测试依赖关系:

Mock<Something> x = new Mock<Something>();
MyObject mockObject = new MyObject(x.Object);

x.Setup(d => d.DoSomething()).Returns(new SomethingElse());

etc

【讨论】:

  • 同意。起订量很棒。他们在一个网页上有完整的操作方法参考。为了易于使用/学习,您不能那样做。
  • 当构造函数需要非空值(带有代码契约或异常)时它是否工作?
  • 例如,如果你有一个整数,你可以传递一个 0。如果它是一个字符串、Null、string.Empty 等。你几乎可以使用 default(T),其中 T :您的参数类型,一切正常。如果您正在制作模拟对象,则标记为虚拟的方法/属性将永远不会被执行;您可以控制他们在模拟对象上做什么(通过回调)或返回什么(通过 Return 方法)。
【解决方案2】:

认为您提供的接口仅用于测试是错误的。接口用于提供抽象并削弱代码不同层之间的耦合,使它们在不同的上下文中更具可重用性。

话虽如此,答案将取决于您使用的模拟框架。例如,您可以使用 Rhino Mocks:

public class Foo
{
    public Foo(string bar)
    { }

    public virtual int SomeMethod()
    {
        return 5;
    }
}

然后:

var fooMock = MockRepository.GeneratePartialMock<Foo>("abc");
fooMock.Expect(x => x.SomeMethod()).Return(10);

【讨论】:

  • 取决于您的观点:确实,开发人员应该编写接口来削弱耦合。错误,如果 QA 可以跳过,他不想仅仅为了测试目的“改进”功能代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-20
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多