【问题标题】:How to Unit test Textrenderer.DrawText method in C#如何在 C# 中对 Textrenderer.DrawText 方法进行单元测试
【发布时间】:2015-09-15 07:23:15
【问题描述】:
public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, TextFormatFlags flags);

我有一个用于我的 ExtendedComboBox 的测试器应用程序。 下面在代码中给出的所有字符串项目都在我的测试应用程序的 ComboBox 项目中。如何对上述方法进行单元测试,因为它返回 void? 测试 TextRenderer.Drawtext 的另一种方法是什么?是否有任何替代方法来测试绘制 ComboBox 文本的 OnDrawItem 方法。

[TestMethod()]
public void ExtendedComboBoxOnDrawPrefixTest()
{
    ExtendedComboBox cboTest = new ExtendedComboBox ();

    // List of strings having special characters.

    string[] items = { 
        "&One",
        "T&wo",
        "E!xclamation",
        "Am@persat",
        "H#ash",
        "Dollar$Sign",
        "Perc%ent",
        "Ci^rcumflex",
        "Ast*erisk",
        "Hy-phen",
        "Und_erscore",
        "pl+us",
        "Equ=als",
        "Col:on",
        "Semi;colon",
        "Co'mma",
        "Inverted\"Comma",
        "Apos'trophe",
        "Pip|e",
        "Open{Brace",
        "Close}Brace",
        "OpenBr[acket",
        "CloseBr]acket",
        "BackS\\lash",
        "ForwardSl/ash",
        "LessT<han",
        "Greate>rThan",
        "Questio?nMark",
        "Do.t",
        "Three",
        "Four",
        "Five",
        "Six",
        "This is a really extremely long string value for a combobox to display."
    };

    cboTest.Items.AddRange(items);

    // To test that all the items have the same kind of prefixes
    for (int index = 0; index < cboTest.Items.Count; index++)
    {
        String expectedText = GetExtendedComboBoxText(cboTest, items[index]);
        Assert.AreEqual(items[index], , String.Format("Item '{0}' returned an string", cboTest.Items[index]));
    }
}

/// <summary>
/// Compare the ComboBoxText of the passed string with respect to the DC, Font, ForeColor and TextFormatFlags.
/// Draw the item 
/// </summary>
private string GetExtendedComboBoxText(Control cboTest, string itemToTest)
{
    TextFormatFlags textFormatflags = TextFormatFlags.NoPrefix;
    Color foreColor = SystemColors.HighlightText;
    return (TextRenderer.DrawText(cboTest.CreateGraphics(), itemToTest, cboTest.Font, new Point(cboTest.Bounds.X, cboTest.Bounds.Y), foreColor, textFormatflags)).Text;
}

【问题讨论】:

  • 通常您不会对返回 void 或不会改变某些对象状态的方法进行单元测试。我能想到的单元测试的唯一方法是将输出渲染到某个图像文件并手动验证它们看起来是否正确,但是如果方法调用成功(不是@ 987654323@),这是你唯一可以测试的东西。
  • @RonBeyer 实际上在这种情况下,OP 不应该测试该方法,因为 Microsoft 已经为我们做了它。(这是一种 BCL 方法)在我的回答中,我会详细解释它。

标签: c# unit-testing


【解决方案1】:

这是一个BCL 方法,您不应该验证 BCL 方法的行为。

在 UT 中有一个假设; BCL 的方法和类可以正常工作。如果您验证 BCL 的方法,那么您将必须验证 intbyteToString() 等的行为...(因为您不能信任您的基础架构)

您不应该验证 BCL 类的行为的底线(Microsoft 已经为您完成了...)。实际上,您应该假设该方法正常工作(而不是验证它),然后验证您使用的方法是否具有正确的参数。

为了帮助我的开发人员,我创建了一个流程图,展示了当他们遇到此类问题时如何采取行动:(在我们的研发中,我们发现它非常有用。我们喜欢它影响我们研发的方式......)

在您的情况下,预期的行为似乎是可见的,因此您可以通过 UI 对其进行验证,作为验收/集成/组件测试的一部分...

如果您仍想将其作为 UT 进行验证,并且您的测试框架不允许您验证(Rhino MocksMoq 等)此方法,则应包装该方法或使用其他工具,例如MsFakesTypemock Isolator 等...

以下 sn-p 演示了使用 MsFakes 对方法设置期望的方法:

    [TestMethod]
    public void PutExpectationOnDrawText()
    {
        var wasExcute = false;
        System.Windows.Forms.Fakes.ShimTextRenderer
                      .DrawTextIDeviceContextStringFontRectangleColorTextFormatFlags =
            (context, txt, font, pt, forecolor, flags) =>
            {
                //the asserts on the orguments...
                //for example:
                Assert.IsNotNull(context);
                Assert.AreNotEqual(String.Empty, txt);
                //...
                wasExcute = true;
            };


        //execute the method which is use DrawText


        Assert.IsTrue(wasExcute);//verify that the method was execute....
    }

【讨论】:

  • 一张漂亮的图表,但我会将您看到的任何“Does it”替换为“Is it”。不确定它是我的强迫症还是什么,但看到“这很容易......”或“值得付出努力”就像我眼中的砾石:) +1
  • 谢谢。这不是你的强迫症,而是我的阅读障碍:-)。此图表是初稿(我在空闲时间在自己的计算机上创建了图表)。该图表已有将近 2 年的历史了,我必须在发布之前修复我的语法错误(在我以前的工作计算机中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多