在C#/.NET中模拟没有参数构造函数的对象

在C#/.NET中模拟没有参数构造函数的对象,c#,.net,reflection,constructor,mocking,C#,.net,Reflection,Constructor,Mocking,可以从不提供无参数构造函数且不向构造函数传递任何参数的类创建模拟吗?也许通过动态创建IL 背景是,我不想只为测试定义接口。解决方法是为测试提供一个无参数构造函数。认为只为测试提供接口是错误的。接口用于提供抽象并削弱代码不同层之间的耦合,使它们在不同上下文中更具可重用性 也就是说,答案将取决于您使用的模拟框架。例如,对于Rhino Mock,您可以: public class Foo { public Foo(string bar) { } public virtual

可以从不提供无参数构造函数且不向构造函数传递任何参数的类创建模拟吗?也许通过动态创建IL


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

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

也就是说,答案将取决于您使用的模拟框架。例如,对于Rhino Mock,您可以:

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);
var fooMock=MockRepository.GeneratePartialMock(“abc”);
Expect(x=>x.SomeMethod()).Return(10);

当然可以。在这个例子中,我将使用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
公共类MyObject
{
公共MyObject(对象A、对象B、对象C)
{
//将依赖项分配给任何对象
}
}
Mock mockObject=new Mock();
Mock mockObject=新的Mock(null,null,null);//将空值传递给特定的构造函数参数,如果为int,则传递0,等等
但在许多情况下,我会将模拟对象指定为参数,以便测试依赖关系:

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

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

etc
Mock x=new Mock();
MyObject mockObject=新的MyObject(x.Object);
x、 Setup(d=>d.DoSomething()).Returns(newsomethingelse());
等

同样从Moq创建mock的用法来看,您需要将这些方法虚拟化。似乎在这种情况下,接口通常更好。不确定其他模拟框架。理想情况下,接口应该在代码中使用;与具体的实现方式相比较,因此对“仅为测试创建接口”的评论成为一个难点。我认为只有一个实现的接口是没有价值的人工制品。作为替代方案,您可以为方法/属性提供virtual关键字,但您会发现接口更好地表达了您的设计,并允许更大程度地将具体实例与使用者分离。同意。Moq真是太棒了。他们在一个网页上有完整的操作指南。为了便于使用/学习,您不能这样做。当构造函数要求非空值(代码契约或异常)时,它是否有效?例如,如果您有一个整数,您可以传递一个0。如果它是一个字符串、Null、string.Empty等等,那么您几乎可以使用默认值(T),其中T:您的参数类型,一切正常。如果您正在创建一个模拟对象,那么将永远不会执行标记为虚拟的方法/属性;您可以控制它们在模拟对象上执行的操作(通过回调)或返回的操作(通过返回方法)。这取决于您的观点:的确,开发人员应该编写接口来削弱耦合。错,QA不想为了测试目的“改进”功能代码,如果他可以跳过的话