我的应用程序(C#、WinForms)是一个图形编辑器,所以绘图是功能的主要部分。我在围绕绘图进行单元测试逻辑时遇到困难,这让我认为我的设计是错误的。让我来描述一下,我想要一些关于如何进行单元测试或如何重构我的应用程序逻辑的建议。

所有绘图均由管理器 (DrawingManager) 处理,该管理器进行几何计算并与显示结果的控件的绘图 Canvas 进行交互。该管理器的典型方法将通过对绘图 Canvas (Graphics)的引用来调用。在应用程序的表面事件(如 OnPaint)中的某个地方,我们将控制权交给管理器,后者决定绘制什么以及如何绘制,然后进行绘制。要绘制,它需要持有对 Graphics 对象的引用,这就是它从事件传递给管理器方法的原因。

    protected override void OnPaint(PaintEventArgs e)
    {
        IZoomBoxDrawingManager drawingManager = ServiceLocator.Instance.Resolve<IZoomBoxDrawingManager>();
        drawingManager.DrawMainImage(this, e.Graphics);
        drawingManager.DrawObjects(this, e.Graphics);

        base.OnPaint(e);
    }

现在,假设 DrawObjects 在开始调用 Graphics 的方法来输出几何之前调用一个逻辑路径或另一个。
我想以某种方式对该管理器中的逻辑进行单元测试,但它与 Graphics 实例的耦合使其在某种程度上变得不可能,至少我不知道如何去做。我用于隔离的最小起订量不能模拟密封类。如果我可以放入某种注册器而不是 Graphics 并且能够查看调用 Graphics 的哪些方法以及何时调用,那将会很不错。
请指教!

最佳答案

考虑使用 Adapter pattern 将 Graphics 对象所需的功能包装在接口(interface)中。

interface IGraphics
{
    void DrawCircle(int x,int y,int d);
}

public class GraphicsAdapter : IGraphics
{
    private readonly Graphics graphics;

    public GraphicsAdapter(Graphics g)
    {
        this.graphics = g;
    }

    public void DrawCircle(int x, int y, int d)
    {
        graphics.DrawCircle(x, y, d);
    }
}

现在您的 DrawingManager 可以依赖于 IGraphics 接口(interface)而不是密封的 Graphics 对象。您可以在测试期间模拟它,但在运行时使用适配器:
drawingManager.DrawObjects(this, new GraphicsAdapter(e.Graphics));

关于c# - 如何单元测试绘制图形?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35074665/

10-12 20:29