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 测试模式。它显示了编写单元测试和模式来避免/修复它们的常见缺陷。
几个月前,我自己也写了一篇关于可测试代码的博客。它有点先进,但也许你可以从中得到一些东西。如果您有任何问题随时问。