使用Moq,如何模拟一个更改流所需的方法作为参数?

时间:2015-04-09 08:32:03

标签: c# unit-testing devexpress moq

我试图测试以下方法:

public void SaveDashboardToPersistentDashboard(
    Dashboard dashboard, PersistentDashboard persistentDashboard)
{
    using (MemoryStream stream = new MemoryStream())
    {
        dashboard.SaveToXml(stream);
        persistentDashboard.Definition = stream.ToArray();

        persistentDashboard.Name = dashboard.Title.Text;
        _unitOfWork.CommitChanges();
    }
}

该方法采用DevExpress仪表板,调用SaveToXml(传入MemoryStream),然后将流数组写入PersistentDashboard POCO的Definition属性

我无法控制Dashboard类,但想要模拟SaveToXml方法以从测试中排除Dashboard方法行为。这将涉及获取内部流并将已知字节数组写入其中。

我是Moq的新手,无法解决如何更改传递给SaveToXml的流的内容 - 至少在没有将流传递到SaveDashboardToPersistentDashboard方法的情况下也是如此。该流是方法行为的附带,因此我并不特别热衷于将其作为参数传递。

有没有办法实现我想要做的事情?

1 个答案:

答案 0 :(得分:3)

这是您的设计问题。不是你使用的模拟库。

如果您希望代码可以测试,直接访问框架通常是一个坏主意。甚至包括.NET框架本身。虽然使用DateTime通常是安全的,但使用File已经成为一个巨大的痛苦。

我建议的是为您使用的DevExpress类创建包装类。然后从您在业务逻辑中使用的接口中提取接口。您可以在测试中模拟它们,没问题。

类似的东西:

public interface IDashboard
{
    void SaveToXml(Stream stream);
}

public class DashboardWrapper : IDashboard
{
    private readonly Dashboard dashboard = new Dashboard();

    public void SaveToXml(Stream stream)
    {
        this.dashboard.SaveToXml(stream);
    }
}

您可以使用抽象工厂或IoC-Container来创建这些包装器。

ETA:不确定如何实例化这些Dashboard个对象。或者,为包装器提供一个构造函数,该构造函数接受Dashboard实例并为使用该构造函数的隐式转换实现operator