跳至页脚内容
.NET 帮助

AutoFixture C#(开发者用法)

AutoFixture is an open-source library for .NET 最小化单元测试书写中的‘安排’阶段,从而改善测试管理。 其主要目的在于使开发者能够专注于他们正在测试的内容,而不是设置过程,通过让您使用测试数据创建对象图。 本文探讨了如何使用 AutoFixture 通过高效的测试数据生成来促进测试驱动开发。

AutoFixture 是 C# 中一个强大的库,旨在简化单元测试的数据创建过程。 它帮助开发人员避免编写重复的设置代码,通过自动生成测试用例的数据。 在单元测试中,AutoFixture 提供了一种生成测试数据的精简方法,确保每个单元测试都能通过多样化且真实的输入来执行。 AutoFixture 通过自动生成测试数据,使 C# 中的测试更加高效,减少手动设置的需求。

AutoFixture C# (开发者如何运作):图1 - AutoFixture

安装和设置 AutoFixture

AutoFixture 可作为 NuGet 包使用,可以通过 NuGet 包管理器控制台或 Visual Studio 的 NuGet 包管理器 UI 中的.NET 添加包进行安装。

Install-Package AutoFixture

NuGet 将下载并安装 AutoFixture 的最新版本及其依赖项到您的项目中。

示例:为类创建测试数据

假设我们有一个简单的员工类,具有 FirstNameLastNameAge 等属性。 我们可以利用 AutoFixture 为我们生成随机数据,而不是在单元测试中手动创建这个类的实例。

public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public Employee(string firstName, string lastName, int age)
    {
        FirstName = firstName;
        LastName = lastName;
        Age = age;
    }

    public string GetFullName() => $"{FirstName} {LastName}";
}
public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public Employee(string firstName, string lastName, int age)
    {
        FirstName = firstName;
        LastName = lastName;
        Age = age;
    }

    public string GetFullName() => $"{FirstName} {LastName}";
}
Public Class Employee
	Public Property FirstName() As String
	Public Property LastName() As String
	Public Property Age() As Integer

	Public Sub New(ByVal firstName As String, ByVal lastName As String, ByVal age As Integer)
		Me.FirstName = firstName
		Me.LastName = lastName
		Me.Age = age
	End Sub

	Public Function GetFullName() As String
		Return $"{FirstName} {LastName}"
	End Function
End Class
$vbLabelText   $csharpLabel

代码描述

Employee 类封装了员工的基本信息,包括他们的名字、姓氏和年龄,由属性 FirstNameLastNameAge 分别表示。 它的构造函数通过接受这些细节作为参数并将其分配给相应的属性来促进员工对象的实例化。 此外,GetFullName 方法将员工的名字和姓氏连接起来,返回全名作为字符串。

为我们的测试场景设置代码

接下来,我们将创建一个测试类,来测试 Employee 类:

using AutoFixture;

public class EmployeeTests
{
    private readonly IFixture _fixture;

    public EmployeeTests()
    {
        // Using AutoFixture's Fixture to create test data
        _fixture = new Fixture();
    }
}
using AutoFixture;

public class EmployeeTests
{
    private readonly IFixture _fixture;

    public EmployeeTests()
    {
        // Using AutoFixture's Fixture to create test data
        _fixture = new Fixture();
    }
}
Imports AutoFixture

Public Class EmployeeTests
	Private ReadOnly _fixture As IFixture

	Public Sub New()
		' Using AutoFixture's Fixture to create test data
		_fixture = New Fixture()
	End Sub
End Class
$vbLabelText   $csharpLabel

代码描述

此代码片段将 AutoFixture 纳入到 Employee 类的单元测试中。 通过导入 AutoFixture 命名空间,开发人员可以访问数据生成功能。 _fixture 字段初始化为 Fixture 的新实例,简化了测试数据的创建。 这个设置提高了员工类全面覆盖的测试效率和可靠性。

示例 1:验证员工测试用例对象的值

[Fact]
public void Employee_ShouldHaveValidValues()
{
    // Arrange
    var firstName = _fixture.Create<string>();
    var lastName = _fixture.Create<string>();
    var age = _fixture.Create<int>();

    // Act
    var employee = new Employee(firstName, lastName, age);

    // Assert
    Assert.Equal(firstName, employee.FirstName);
    Assert.Equal(lastName, employee.LastName);
    Assert.Equal(age, employee.Age);
}
[Fact]
public void Employee_ShouldHaveValidValues()
{
    // Arrange
    var firstName = _fixture.Create<string>();
    var lastName = _fixture.Create<string>();
    var age = _fixture.Create<int>();

    // Act
    var employee = new Employee(firstName, lastName, age);

    // Assert
    Assert.Equal(firstName, employee.FirstName);
    Assert.Equal(lastName, employee.LastName);
    Assert.Equal(age, employee.Age);
}
<Fact>
Public Sub Employee_ShouldHaveValidValues()
	' Arrange
	Dim firstName = _fixture.Create(Of String)()
	Dim lastName = _fixture.Create(Of String)()
	Dim age = _fixture.Create(Of Integer)()

	' Act
	Dim employee As New Employee(firstName, lastName, age)

	' Assert
	Assert.Equal(firstName, employee.FirstName)
	Assert.Equal(lastName, employee.LastName)
	Assert.Equal(age, employee.Age)
End Sub
$vbLabelText   $csharpLabel

代码描述

测试方法 Employee_ShouldHaveValidValues 验证 Employee 类是否正确初始化其属性。 使用测试装置生成 FirstNameLastNameAge的随机数据,测试创建了一个 Employee 实例。 然后,它断言 Employee 对象的 FirstNameLastNameAge 属性是否匹配生成的值,确保构造函数准确设置这些属性。

示例 2:验证调用构造函数时的员工

[Fact]
public void CreateEmployee_ValidData_ReturnsEmployeeObject()
{
    // Arrange
    var employee = _fixture.Create<Employee>();

    // Act 
    // Assert
    Assert.NotNull(employee);
    Assert.False(string.IsNullOrEmpty(employee.FirstName));
    Assert.NotNull(employee.LastName);
    Assert.True(employee.Age > 0);
}
[Fact]
public void CreateEmployee_ValidData_ReturnsEmployeeObject()
{
    // Arrange
    var employee = _fixture.Create<Employee>();

    // Act 
    // Assert
    Assert.NotNull(employee);
    Assert.False(string.IsNullOrEmpty(employee.FirstName));
    Assert.NotNull(employee.LastName);
    Assert.True(employee.Age > 0);
}
<Fact>
Public Sub CreateEmployee_ValidData_ReturnsEmployeeObject()
	' Arrange
	Dim employee = _fixture.Create(Of Employee)()

	' Act 
	' Assert
	Assert.NotNull(employee)
	Assert.False(String.IsNullOrEmpty(employee.FirstName))
	Assert.NotNull(employee.LastName)
	Assert.True(employee.Age > 0)
End Sub
$vbLabelText   $csharpLabel

代码描述

此测试方法包含测试断言,验证 Employee 对象的属性是否匹配随机生成的值。 它确认 string 类型属性 FirstNameLastName,以及 int 类型的 Age 是否正确设置和有效。 任何失败的断言都会表示预期值与为员工详细信息生成的随机值之间的差异。

AutoFixture C# (开发人员运作):图2 - 有效员工数据单元测试

Introducing IronPDF

IronPDF C# PDF Library is a robust C# PDF library developed by Iron Software that facilitates the reading of PDF text and the 使用 HTML 创建 PDF 文档。 这种多功能工具能够将易于格式化的文档(包括样式信息)转换为高质量的 PDF。 使用 IronPDF,从 HTML 文本生成 PDFs 是一个无缝过程,允许用户从 URL 中提取 HTML 内容,并将其转换为结构良好的 PDF 文件。 这一功能使得 IronPDF 成为开发人员希望直接从 Web 内容自动化和简化创建专业 PDF 文档的必备工具。

AutoFixture C# (开发人员运作):图3 - IronPDF

安装 IronPDF。

打开 NuGet 包管理器控制台,并运行以下命令:

Install-Package IronPdf

使用 AutoFixture 功能与 IronPDF 的代码示例

以下示例演示了同时使用 AutoFixture 和 IronPDF 生成员工数据的 PDF:

using DemoAutofixture;
using IronPdf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class EmployeePdfGenerator
{
    private readonly Fixture _fixture;

    public EmployeePdfGenerator()
    {
        _fixture = new Fixture();
    }

    public List<Employee> GenerateEmployees(int count)
    {
        return _fixture.CreateMany<Employee>(count).ToList();
    }

    public void GeneratePdf(List<Employee> employees, string filePath)
    {
        IronPdf.License.LicenseKey = "Your-License-Key-Here";
        var renderer = new ChromePdfRenderer();
        string htmlContent = GenerateHtml(employees);

        try
        {
            renderer.RenderHtmlAsPdf(htmlContent).SaveAs(filePath);
            Console.WriteLine("PDF Created Successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error generating PDF: {ex.Message}");
        }
    }

    private string GenerateHtml(List<Employee> employees)
    {
        StringBuilder htmlBuilder = new StringBuilder();
        htmlBuilder.Append("<!DOCTYPE html><html><head><title>Employee List</title></head><body><h1>Employee List</h1><ul>");

        foreach (var employee in employees)
        {
            htmlBuilder.Append($"<li>{employee.GetFullName()} - Age: {employee.Age}</li>");
        }

        htmlBuilder.Append("</ul></body></html>");
        return htmlBuilder.ToString();
    }
}
using DemoAutofixture;
using IronPdf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class EmployeePdfGenerator
{
    private readonly Fixture _fixture;

    public EmployeePdfGenerator()
    {
        _fixture = new Fixture();
    }

    public List<Employee> GenerateEmployees(int count)
    {
        return _fixture.CreateMany<Employee>(count).ToList();
    }

    public void GeneratePdf(List<Employee> employees, string filePath)
    {
        IronPdf.License.LicenseKey = "Your-License-Key-Here";
        var renderer = new ChromePdfRenderer();
        string htmlContent = GenerateHtml(employees);

        try
        {
            renderer.RenderHtmlAsPdf(htmlContent).SaveAs(filePath);
            Console.WriteLine("PDF Created Successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error generating PDF: {ex.Message}");
        }
    }

    private string GenerateHtml(List<Employee> employees)
    {
        StringBuilder htmlBuilder = new StringBuilder();
        htmlBuilder.Append("<!DOCTYPE html><html><head><title>Employee List</title></head><body><h1>Employee List</h1><ul>");

        foreach (var employee in employees)
        {
            htmlBuilder.Append($"<li>{employee.GetFullName()} - Age: {employee.Age}</li>");
        }

        htmlBuilder.Append("</ul></body></html>");
        return htmlBuilder.ToString();
    }
}
Imports DemoAutofixture
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text

Public Class EmployeePdfGenerator
	Private ReadOnly _fixture As Fixture

	Public Sub New()
		_fixture = New Fixture()
	End Sub

	Public Function GenerateEmployees(ByVal count As Integer) As List(Of Employee)
		Return _fixture.CreateMany(Of Employee)(count).ToList()
	End Function

	Public Sub GeneratePdf(ByVal employees As List(Of Employee), ByVal filePath As String)
		IronPdf.License.LicenseKey = "Your-License-Key-Here"
		Dim renderer = New ChromePdfRenderer()
		Dim htmlContent As String = GenerateHtml(employees)

		Try
			renderer.RenderHtmlAsPdf(htmlContent).SaveAs(filePath)
			Console.WriteLine("PDF Created Successfully!")
		Catch ex As Exception
			Console.WriteLine($"Error generating PDF: {ex.Message}")
		End Try
	End Sub

	Private Function GenerateHtml(ByVal employees As List(Of Employee)) As String
		Dim htmlBuilder As New StringBuilder()
		htmlBuilder.Append("<!DOCTYPE html><html><head><title>Employee List</title></head><body><h1>Employee List</h1><ul>")

		For Each employee In employees
			htmlBuilder.Append($"<li>{employee.GetFullName()} - Age: {employee.Age}</li>")
		Next employee

		htmlBuilder.Append("</ul></body></html>")
		Return htmlBuilder.ToString()
	End Function
End Class
$vbLabelText   $csharpLabel

要使用此类,您将实例化 EmployeePdfGenerator,生成员工列表,然后调用 GeneratePdf

List<Employee> employees = new()
{
    new Employee("John", "Smith", 32),
    new Employee("Emily", "Davis", 18),
    new Employee("David", "Brown", 24),
    new Employee("Jane", "Doe", 16),
    new Employee("Michael", "Johnson", 49),
};

EmployeePdfGenerator pdfGenerator = new();
pdfGenerator.GeneratePdf(employees, "EmployeeList.pdf");
List<Employee> employees = new()
{
    new Employee("John", "Smith", 32),
    new Employee("Emily", "Davis", 18),
    new Employee("David", "Brown", 24),
    new Employee("Jane", "Doe", 16),
    new Employee("Michael", "Johnson", 49),
};

EmployeePdfGenerator pdfGenerator = new();
pdfGenerator.GeneratePdf(employees, "EmployeeList.pdf");
Dim employees As New List(Of Employee)() From {
	New Employee("John", "Smith", 32),
	New Employee("Emily", "Davis", 18),
	New Employee("David", "Brown", 24),
	New Employee("Jane", "Doe", 16),
	New Employee("Michael", "Johnson", 49)
}

Dim pdfGenerator As New EmployeePdfGenerator()
pdfGenerator.GeneratePdf(employees, "EmployeeList.pdf")
$vbLabelText   $csharpLabel

AutoFixture C# (开发人员运作):图4 - AutoFixture 与 IronPDF 输出

代码描述

提供的 C# 代码使用 IronPDF 库生成列出员工及其年龄的 PDF 文档。 它定义了一个包含 GeneratePdf 方法的 EmployeePdfGenerator 类,该方法接受一个 Employee 对象列表和一个文件路径。 它通过 GenerateHtml 方法构造 HTML 内容,然后使用 IronPDF 的 HtmlToPdf 类将此 HTML 渲染为 PDF,保存在指定的文件路径中。 增强功能包括使用 StringBuilder 进行 HTML 生成,并为 PDF 生成和文件保存添加基本错误处理。

编写测试方法

在下面的设置中,AutoFixture 用于创建 Employee 类的实例,支持生成用于测试的随机数据。 IronPDF 被用于将包括员工信息的 HTML 内容无缝转换为 PDF 格式。 EmployeePdfGenerator 类协调这些过程,高效管理数据生成和 PDF 转换。 与此同时,EmployeePdfGeneratorTests XUnit 测试类通过严格的测试确保 PDF 生成的正常功能。 这种综合方法简化了员工数据的生成和文档化,确保 PDF 生成过程的健壮性和可靠性。

using System.IO;
using Xunit;

public class EmployeePdfGeneratorTests
{
    [Fact]
    public void GeneratePdf_GeneratesPdfFile()
    {
        // Arrange
        var generator = new EmployeePdfGenerator();
        var employees = generator.GenerateEmployees(5);
        string filePath = "EmployeeList.pdf";

        // Act
        generator.GeneratePdf(employees, filePath);

        // Assert
        Assert.True(File.Exists(filePath));
    }
}
using System.IO;
using Xunit;

public class EmployeePdfGeneratorTests
{
    [Fact]
    public void GeneratePdf_GeneratesPdfFile()
    {
        // Arrange
        var generator = new EmployeePdfGenerator();
        var employees = generator.GenerateEmployees(5);
        string filePath = "EmployeeList.pdf";

        // Act
        generator.GeneratePdf(employees, filePath);

        // Assert
        Assert.True(File.Exists(filePath));
    }
}
Imports System.IO
Imports Xunit

Public Class EmployeePdfGeneratorTests
	<Fact>
	Public Sub GeneratePdf_GeneratesPdfFile()
		' Arrange
		Dim generator = New EmployeePdfGenerator()
		Dim employees = generator.GenerateEmployees(5)
		Dim filePath As String = "EmployeeList.pdf"

		' Act
		generator.GeneratePdf(employees, filePath)

		' Assert
		Assert.True(File.Exists(filePath))
	End Sub
End Class
$vbLabelText   $csharpLabel

这里 EmployeePdfGeneratorTests 类包含验证在指定文件路径中创建 PDF 文件的测试用例,以确保 GeneratePdf 方法正常运作。

AutoFixture C# (开发人员运作):图5 - AutoFixture C#

结论

AutoFixture 简化了 .NET 中单元测试书写的‘安排’阶段,为开发人员提供了一种专注于测试用例而不是设置细节的方法。 它简化了单元测试过程,通过自动生成测试数据确保多样化且真实的输入。 结合IronPDF 授权信息,提供了一个用于持续使用和支持的强大组合。

常见问题解答

如何使用AutoFixture在C#中生成测试数据?

您可以使用AutoFixture通过其“Fixture”类在C#中生成测试数据。该类允许您自动创建带有随机数据的类实例,这可以用于高效地设置各种测试场景。

AutoFixture在.NET项目中的安装步骤是什么?

要在.NET项目中安装AutoFixture,您可以使用NuGet包管理器控制台并运行命令Install-Package AutoFixture。也可以通过Visual Studio的NuGet包管理器UI搜索AutoFixture并将其添加到项目中。

AutoFixture如何改善单元测试过程?

AutoFixture通过自动生成现实且多样化的测试数据来增强单元测试过程。这减少了手动设置的需求,并确保测试在各种输入下进行,从而提高了测试覆盖率和可靠性。

AutoFixture可以与.NET中的PDF生成库集成吗?

可以,AutoFixture可以与如IronPDF这样的PDF生成库集成在.NET中。通过使用AutoFixture生成数据,您可以创建包含动态内容的PDF,例如员工数据,利用IronPDF将HTML转换为PDF的能力。

AutoFixture中‘Fixture’类的目的是什么?

AutoFixture中的‘Fixture’类旨在通过自动创建测试数据简化测试设置。它生成带有随机数据的类实例,使开发人员能更专注于测试逻辑而不是手动设置数据。

AutoFixture如何促进测试驱动开发(TDD)?

AutoFixture通过提供简便的方法生成测试数据来支持测试驱动开发(TDD),使开发者能够在不花费过多时间进行数据设置的情况下编写测试并实现功能,从而简化TDD过程,使其更高效。

如何在C#中使用AutoFixture和PDF库自动生成文档?

您可以通过结合AutoFixture和像IronPDF这样的PDF库来在C#中自动生成文档。AutoFixture可以生成文档所需的数据,而IronPDF可以高效地将格式化为HTML的数据转换为PDF文档。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。