【问题标题】:What is a unit test and how do I do one in Visual Studio with C# .Net什么是单元测试以及如何在 Visual Studio 中使用 C# .Net 进行单元测试
【发布时间】:2012-06-13 12:18:49
【问题描述】:

好的,所以我在 C# 中有以下类:

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass("Hello World");
        myClass.WriteToConsole();
    }
}

class MyClass
{
    private string MyProperty { get; set; }

    public MyClass(string textToEncapsulate)
    {
        MyProperty = textToEncapsulate;
    }

    public void WriteToConsole()
    {
        Console.WriteLine(MyProperty);
    }
}

三个问题:

  1. 什么是单元测试?
  2. 单元测试在上面的例子中是否有用?
  3. 我将如何进行上述示例的“单元测试”?

谢谢

【问题讨论】:

  • 你做过研究吗?
  • 我近距离投票的原因:这个问题过于宽泛,缺乏“你已经尝试过什么”的证据。
  • 是的,我找到了很多一般信息,但我正在寻找 .Net 和 Visual Studio 上下文中的答案

标签: c# visual-studio-2010 unit-testing


【解决方案1】:

1.什么是单元测试?

手动测试非常耗时。每次手动运行完全相同的一组测试以确保代码的所有部分都按预期运行可能很困难。在手动测试一个完整的产品时,测试所有代码路径也非常困难。

当数据库不可用时,您将如何测试代码的反应?或者当存储了一些错误的数据时?这需要相当长的时间才能做好。

单元测试意味着我们开始测试代码中尽可能小的部分。为了确保我们可以轻松地做到这一点,我们将流程自动化。这意味着我们编写测试代码来测试我们的生产代码。

例如:

int a = 3;
int b = 5;

Calculator c = new Calculator();
int sum = c.Sum(a, b);

Assert.AreEqual(8, sum);

此测试可确保您的 Calculator 类上的 Sum 函数正常工作。

现在,假设您要优化 Calculator 类的内部工作。您开始更改和优化代码。每次更改后,您都运行单元测试,当它们都成功时,您就知道您没有破坏任何代码。

假设在生产环境中,用户为您的计算器提交了错误报告。您的第一步将是编写一个显示此错误的单元测试。在新测试失败后(因为 bug 仍然存在!)你修复了 bug,单元测试成功了,你可以确定这个 bug 永远不会再出现。

这种安全带是单元测试的最大好处之一。

2 在上面的例子中,单元测试会有用吗? 3 我将如何进行上述示例的“单元测试”?

单元测试是一种很好的做法。它可以帮助您证明您的代码正在运行。但是,在您的示例中,很难测试代码。

控制台的输出不是可以轻易测试的。但是,如果您将 Console.WriteLine 的概念抽象出来,那么您的代码将变得更好的可测试性。

编写单元测试实际上非常简单。问题在于编写可以实际测试的代码。

您的代码的更好的可测试版本是:

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass(new ConsoleOutputService(), "Hello World");
        myClass.WriteToConsole();
    }
}

public interface IOutputService
{

    void WriteLine(string MyProperty);
}

public class ConsoleOutputService : IOutputService
{
    public void WriteLine(string MyProperty)
    {
        Console.WriteLine(MyProperty);
    }
}

class MyClass
{
    private IOutputService _outputService;
    private string MyProperty { get; set; }

    public MyClass(IOutputService outputService, string textToEncapsulate)
    {
        _outputService = outputService;
        MyProperty = textToEncapsulate;
    }

    public void WriteToConsole()
    {
        _outputService.WriteLine(MyProperty);

    }
}

您已将您对控制台的直接依赖替换为接口。在对该代码进行单元测试时,您可以为您的 IOutputService 提供一个假的并检查结果。

一本非常好的书是xUnit Test Patterns。它展示了编写单元测试的常见缺陷以及避免/修复它们的模式。

几个月前,我自己也 wrote a blog 谈到了可测试代码。它有点先进,但也许你可以从中得到一些东西。如果您有任何问题,请随时提出。

【讨论】:

  • 谢谢!这个答案很有意义,值得所有的反对=)
【解决方案2】:

您提出的类不是那么可测试的,因为它直接在控制台上运行。如果您更改方法WriteToConsole(TextWriter out); 会有所不同。在这种情况下,您可以模拟 TextWriter 并断言该类输出到控制台正是您所期望的。这个想法是,如果您编写可测试的代码,您就会编写更好的代码,因为为可测试性工作会使您的代码更易于重用。即使在您的情况下进行单元测试似乎有点傻,但有一个测试证明简单的行为有效,可以让您在您或其他人进行进一步修改时更安全,这可能会作为副作用改变您定义的期望.请注意,我建议您使用一个简单的 TextWriter 作为附加参数来使您的类可测试:我认为您必须做最简单的努力才能使您的类可测试,并且由于 TextWriter 是可模拟的,因此您可以获得测试的好处无需重写整个代码,这通常很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多