.net 有可能用Moq得到一个模拟接口的示例吗?

bpsygsoo  于 2022-12-30  发布在  .NET
关注(0)|答案(1)|浏览(134)

假设我有两个类,设置如下:

public class ClassAImpl : IInterfaceA
{
    private ClassBImpl _someObject;

    public ClassAImpl() { }

    public IInterfaceB prepare
    {
        get
        {
            if (_someObject == null)
                _someObject = new ClassBImpl();

            return _someObject;
        }
    }

}

public interface IInterfaceB
{
    string doSomething(int p);
}

public class ClassBImpl : IInterfaceB
{
    public ClassBImpl() { }

    public string doSomething(int p)
    {
        return "hi";
    }
}

我的最终目标是能够模拟doSomething的返回值,通过ClassBImpl示例中的对象。现在,使用接口单独模拟已经足够容易了。但是我不能将IInterfaceB的模拟接口传递到ClassAImpl中,因为我需要的是对象,而不是接口。我不能覆盖方法本身,因为它不是虚拟的。
是否有可能模拟一个接口,然后从它创建一个对象?

q8l4jmvw

q8l4jmvw1#

代码中有问题的行如下

_someObject = new ClassBImpl()

要删除对具体类的直接依赖,可以创建一个接受工厂的构造函数,并将_someObject更改为接口类型。

public class ClassAImpl : IInterfaceA
{
    private IInterfaceB _someObject;
    private IFactory _factory;

    public ClassAImpl(IFactory factory) => _factory = factory;

    public IInterfaceB prepare
    {
        get
        {
            if (_someObject == null)
                _someObject = _factory.Create();

            return _someObject;
        }
    }
}

然后对IFactoryConcreteFactoryMockFactory进行编码。

public interface IFactory
{
    IInterfaceB Create();
}

public class ConcreteFactory : IFactory
{
    IInterfaceB Create() => new ClassBImpl();
}

public class MockFactory : IFactory
{
    IInterfaceB Create()
    {
        var mock = new Mock<IInterfaceB>().CreateMock();
        // TODO here: mock the doSomething() method
        return mock.Object;
    }
}

回到测试中,您可以执行以下操作

var a = new ClassAImpl(new MockFactory());
...

在您的生产代码中,您可以执行以下操作

var a = new ClassAImpl(new ConcreteFactory());
...

相关问题