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

Using Moq, how do I mock a method that changes a stream it takes as a parameter?

我正在尝试测试以下方法:

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 属性.

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

我是 Moq 的新手,不知道如何更改传递到 SaveToXml 的流的内容 - 至少在不将流传递到 SaveDashboardToPersistentDashboard 方法的情况下是这样。流对于方法的行为是附带的,所以我不是特别热衷于将它作为参数传递。

有什么方法可以实现我想要做的事情吗?

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

如果您希望代码可测试,直接访问框架通常不是一个好主意。这甚至包括 .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 容器来创建这些包装器。

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