跳過到頁腳內容
.NET幫助

Moq C#(開發者的工作原理)

在軟體開發領域,測試是不可或缺的過程。 它能確保你的程式碼按預期運行,並有助於在錯誤進入生產環境之前將其捕獲。 測試的一個重要方面是模擬,而對於 C# 測試來說,MOQ 是開發人員武器庫中的強大工具。 它為 lambda 表達式提供支援。 MOQ,即" .NET模擬物件框架",簡化了創建用於單元測試的模擬物件的過程。 本文將深入探討 C# 中的 MOQ。

什麼是最小起訂量(MOQ)?

MOQ - Mocking Framework for .NET是一個用於.NET應用程式的模擬框架,它允許開發人員快速且有效率地建立模擬物件。 模擬物件可以模擬應用程式中真實物件的行為,從而更容易隔離和測試程式碼的特定部分。 MOQ 簡化了建立和使用這些模擬物件的過程。

最小訂貨量的關鍵特徵

*流暢的介面:* MOQ 提供流暢且富有表現力的 API,用於設定預期和驗證。 這樣可以讓你的測試程式碼更易讀、更易理解。 強型別: MOQ 利用 C# 語言特性,在定義類比物件和期望物件時提供強型別和 IntelliSense 支援。 這樣可以降低測試中出現運行時錯誤的幾率。 寬鬆模擬: MOQ 支援嚴格和寬鬆的模擬。 寬鬆模擬可讓您建立回應任何方法呼叫的模擬對象,而嚴格模擬則強制只呼叫預期的方法。 可驗證的行為:** MOQ 可讓您驗證模擬物件上的特定方法是否已使用預期的參數以正確的順序呼叫。 *回調和傳回值:您可以定義回呼函數,以便在呼叫模擬方法時執行自訂程式碼,並指定模擬方法的傳回值。

最小起訂量入門

在本教程中,我們將探討如何使用 MOQ(一個流行的 C# 模擬框架)來簡化單元測試。 我們將透過一個範例來示範如何使用 MOQ 來模擬依賴項,從而建立和測試一個簡單的 ATM 交易場景。

建立一個新的 C# 項目

請依照以下步驟建立新項目:

  1. 開啟Visual Studio ,前往"檔案">"新建">"專案..."。
  2. 選擇專案模板,配置設置,然後按一下"建立"。

Moq C#(開發者使用方法)圖 1 - 在 Visual Studio 2022 中建立新的控制台應用程式

假設你正在開發一款 ATM(自動櫃員機)軟體,並且需要測試其身份驗證和提款功能。 ATM 依賴兩個介面:IHostBankIHSMModule。 我們想要測試 ATMCashWithdrawal 類,該類代表 ATM 的提款功能。

建立兩個接口,IHostBankIHSMModule,它們代表 ATM 系統的依賴關係。 定義相關方法,例如 AuthenticateAmountValidatePIN

// IHostBank.cs
public interface IHostBank
{
    bool AuthenticateAmount(string accountNumber, int amount);
}

// IHSMModule.cs
public interface IHSMModule
{
    bool ValidatePIN(string cardNumber, int pin);
}
// IHostBank.cs
public interface IHostBank
{
    bool AuthenticateAmount(string accountNumber, int amount);
}

// IHSMModule.cs
public interface IHSMModule
{
    bool ValidatePIN(string cardNumber, int pin);
}
$vbLabelText   $csharpLabel

建立 ATMCashWithdrawal 類,該類使用上述依賴項來執行 ATM 操作。 在這個類別中,你將實作一個類似 WithdrawAmount 的特定方法。

// ATMCashWithdrawal.cs
public class ATMCashWithdrawal
{
    private readonly IHSMModule hsmModule;
    private readonly IHostBank hostBank;

    public ATMCashWithdrawal(IHSMModule hsmModule, IHostBank hostBank)
    {
        this.hsmModule = hsmModule;
        this.hostBank = hostBank;
    }

    // Withdraw amount after validating PIN and balance
    public bool WithdrawAmount(string cardNumber, int pin, int amount)
    {
        if (!hsmModule.ValidatePIN(cardNumber, pin))
        {
            return false;
        }

        if (!hostBank.AuthenticateAmount(cardNumber, amount))
        {
            return false;
        }

        // Withdraw the specified amount and perform other operations
        return true;
    }
}
// ATMCashWithdrawal.cs
public class ATMCashWithdrawal
{
    private readonly IHSMModule hsmModule;
    private readonly IHostBank hostBank;

    public ATMCashWithdrawal(IHSMModule hsmModule, IHostBank hostBank)
    {
        this.hsmModule = hsmModule;
        this.hostBank = hostBank;
    }

    // Withdraw amount after validating PIN and balance
    public bool WithdrawAmount(string cardNumber, int pin, int amount)
    {
        if (!hsmModule.ValidatePIN(cardNumber, pin))
        {
            return false;
        }

        if (!hostBank.AuthenticateAmount(cardNumber, amount))
        {
            return false;
        }

        // Withdraw the specified amount and perform other operations
        return true;
    }
}
$vbLabelText   $csharpLabel

建立單元測試項目

現在,讓我們使用 MOQ 模擬依賴項,為 ATMCashWithdrawal 類別建立單元測試。

在您的解決方案中建立一個新的單元測試項目,並將其命名為 ATMSystem.Tests

若要將 NUnit 測試專案新增至 Visual Studio 解決方案中,請依照下列步驟操作:

1.右鍵單擊解決方案:在解決方案資源管理器(通常在右側)中,以滑鼠右鍵按一下解決方案名稱。 2.新增 > 新項目:從上下文選單中,選擇"新增",然後選擇"新建項目..."。 3.建立新項目:在"新增項目"對話方塊中,您可以搜尋"NUnit"以尋找可用的 NUnit 範本。 選擇如下所示的 NUnit 測試項目。

Moq C#(開發者使用方法)圖 2 - 在解決方案中新增新的 NUnit 測試項目。

4.配置項目:根據需要配置項目設置,包括項目名稱和位置。 5.按一下"確定":按一下"建立"或"確定"按鈕,將 NUnit 測試項目新增至您的解決方案。

現在,您的解決方案中有一個獨立的 NUnit 測試項目,您可以在其中編寫和管理單元測試。 您也可以新增對要測試的專案的引用,並開始在該專案中編寫 NUnit 測試案例。

要開始在測試專案中使用 MOQ,您需要將 MOQ NuGet套件新增至您的解決方案。 您可以使用 Visual Studio 中的NuGet套件管理器來完成此操作,也可以在套件管理器控制台中執行下列命令:

Install-Package Moq

此命令將安裝軟體包並將所有必要的依賴項新增至專案。

使用 NUnit 和 MOQ 編寫單元測試,模擬 ATMCashWithdrawal 類別的依賴項(IHostBankIHSMModule)。

using Moq;
using NUnit.Framework;

namespace ATMSystem.Tests
{
    public class ATMTests
    {
        private ATMCashWithdrawal atmCash;

        [SetUp]
        public void Setup()
        {
            // Arrange - Setup mock objects
            var hsmModuleMock = new Mock<IHSMModule>();
            hsmModuleMock.Setup(h => h.ValidatePIN("123456781234", 1234)).Returns(true);

            var hostBankMock = new Mock<IHostBank>();
            hostBankMock.Setup(h => h.AuthenticateAmount("123456781234", 500)).Returns(true);

            atmCash = new ATMCashWithdrawal(hsmModuleMock.Object, hostBankMock.Object);
        }

        [Test]
        public void WithdrawAmount_ValidTransaction_ReturnsTrue()
        {
            // Act - Execute the method under test
            bool result = atmCash.WithdrawAmount("123456781234", 1234, 500);

            // Assert - Verify the result
            Assert.IsTrue(result);
        }

        // More test cases for different scenarios (e.g., invalid PIN, insufficient funds)
    }
}
using Moq;
using NUnit.Framework;

namespace ATMSystem.Tests
{
    public class ATMTests
    {
        private ATMCashWithdrawal atmCash;

        [SetUp]
        public void Setup()
        {
            // Arrange - Setup mock objects
            var hsmModuleMock = new Mock<IHSMModule>();
            hsmModuleMock.Setup(h => h.ValidatePIN("123456781234", 1234)).Returns(true);

            var hostBankMock = new Mock<IHostBank>();
            hostBankMock.Setup(h => h.AuthenticateAmount("123456781234", 500)).Returns(true);

            atmCash = new ATMCashWithdrawal(hsmModuleMock.Object, hostBankMock.Object);
        }

        [Test]
        public void WithdrawAmount_ValidTransaction_ReturnsTrue()
        {
            // Act - Execute the method under test
            bool result = atmCash.WithdrawAmount("123456781234", 1234, 500);

            // Assert - Verify the result
            Assert.IsTrue(result);
        }

        // More test cases for different scenarios (e.g., invalid PIN, insufficient funds)
    }
}
$vbLabelText   $csharpLabel

在本測試程式碼中,我們使用 MOQ 為 IHSMModuleIHostBank 建立模擬對象,並指定它們在測試期間被呼叫時的行為。

在上面的程式碼範例中,我們示範了在 C# 中使用 MOQ 模擬物件的概念。 我們為 IHSMModuleIHostBank 介面建立模擬對象,模擬它們在單元測試期間的行為。 這樣,我們就可以透過控制這些模擬物件的反應來隔離並徹底測試 ATMCashWithdrawal 類別。 透過模擬,我們可以確保我們的程式碼與這些依賴項正確交互,從而使我們的測試更有針對性、可預測性,並能有效地識別正在檢查的特定程式碼單元中的問題。 這種做法提高了整體可靠性、可維護性和測試程式碼品質。

步驟三:運行測試

  1. 建立您的解決方案,確保所有內容都是最新的。
  2. 在 Visual Studio 中開啟測試資源管理器(測試 > 測試資源管理器)。
  3. 在測試資源管理器中按一下"全部執行"按鈕以執行單元測試。
  4. 查看測試結果。 你應該看到你寫的測試(WithdrawAmount_ValidTransaction_ReturnsTrue)通過了。

![Moq C#(開發人員的工作原理)圖 3 - 要執行測試,首先必須建立解決方案。 建置成功後,開啟 Visual Studio 中的"測試資源管理器",然後按一下"全部執行"按鈕開始執行單元測試。

這樣,我們就可以隔離要測試的程式碼,並透過有效地模擬依賴項來確保其在各種情況下都能如預期運作。 這種做法可以提高軟體的可靠性和可維護性,使在開發過程早期更容易發現和解決問題。

IronPDF簡介

IronPDF文件和功能概述是一個強大的 C# 庫,可讓開發人員在其應用程式中處理 PDF 文件。 它提供了廣泛的功能,包括創建、修改和轉換來自各種來源(如 HTML、圖像和現有 PDF)的 PDF 文件。 結合上一篇教學中討論的模擬物件概念, IronPDF可以成為在單元測試中產生和操作 PDF 文件的寶貴工具。

IronPDF 的主要特點是其HTML 轉 PDF功能,確保佈局和樣式保持不變。 它可以將網頁內容轉換為 PDF 文件,非常適合用於報告、發票和文件。 此功能支援將 HTML 檔案、URL 和 HTML 字串轉換為 PDF。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
$vbLabelText   $csharpLabel

例如,如果您有一個涉及 PDF 生成或處理的項目,您可以使用IronPDF建立模擬真實場景的模擬 PDF 文件。 這對於測試和驗證程式碼如何與 PDF 文件互動尤其有用。 您可以產生具有特定內容、佈局和屬性的模擬 PDF,然後將其用作測試工具,以確保您的程式碼能夠產生所需的 PDF 輸出或正確處理與 PDF 相關的操作。

建立用於生成 PDF 的模擬對象

假設您正在開發一個產生財務報告的應用程序,並且這些報告需要儲存為 PDF 文件並進行分發。 在這種情況下,您可能需要測試 PDF 產生情況,並確保內容和格式正確。

首先,我們需要將IronPDF加入到我們的專案中。 在NuGet套件管理器控制台中輸入以下命令來安裝IronPDF。

Install-Package IronPdf

此命令將安裝並向我們的專案添加必要的依賴項。

以下是如何將IronPDF整合到單元測試流程中的方法:

生成模擬PDF

您可以使用IronPDF建立具有特定內容和樣式的模擬 PDF 文檔,以模仿真實的財務報告。 這些模擬 PDF 檔案可以用作單元測試的測試案例,如下面的程式碼片段所示:

public class PDFGenerator
{
    public void GenerateFinancialReport(string reportData)
    {
        var renderer = new ChromePdfRenderer();

        // Generate the report HTML
        string reportHtml = GenerateReportHtml(reportData);
        PdfDocument pdfDocument = renderer.RenderHtmlAsPdf(reportHtml);

        // Save the PDF to a file or memory stream
        pdfDocument.SaveAs("FinancialReport.pdf");
    }

    private string GenerateReportHtml(string reportData)
    {
        // Generate the report HTML based on the provided data
        // (e.g., using Razor views or any HTML templating mechanism)
        // Return the HTML as a string
        return "<h1>my Report</h1>";
    }
}
public class PDFGenerator
{
    public void GenerateFinancialReport(string reportData)
    {
        var renderer = new ChromePdfRenderer();

        // Generate the report HTML
        string reportHtml = GenerateReportHtml(reportData);
        PdfDocument pdfDocument = renderer.RenderHtmlAsPdf(reportHtml);

        // Save the PDF to a file or memory stream
        pdfDocument.SaveAs("FinancialReport.pdf");
    }

    private string GenerateReportHtml(string reportData)
    {
        // Generate the report HTML based on the provided data
        // (e.g., using Razor views or any HTML templating mechanism)
        // Return the HTML as a string
        return "<h1>my Report</h1>";
    }
}
$vbLabelText   $csharpLabel

使用模擬 PDF 進行單元測試

我們將編寫測試案例,使用IronPDF產生模擬 PDF 文件,以代表各種報告場景。 然後,我們將把程式碼產生的實際 PDF 與這些模擬 PDF 進行比較,以確保內容、格式和結構符合預期。

using IronPdf;
using NUnit.Framework;

internal class PDFGeneratorTests
{
    [Test]
    public void GenerateFinancialReport_CreatesCorrectPDF()
    {
        // Arrange
        var pdfGenerator = new PDFGenerator();
        var expectedPdf = PdfDocument.FromFile("ExpectedFinancialReport.pdf"); // Load a mock PDF

        // Act
        pdfGenerator.GenerateFinancialReport("Sample report data");
        var actualPdf = PdfDocument.FromFile("FinancialReport.pdf");

        // Assert
        Assert.AreEqual(actualPdf.ExtractAllText(), expectedPdf.ExtractAllText());
    }
}
using IronPdf;
using NUnit.Framework;

internal class PDFGeneratorTests
{
    [Test]
    public void GenerateFinancialReport_CreatesCorrectPDF()
    {
        // Arrange
        var pdfGenerator = new PDFGenerator();
        var expectedPdf = PdfDocument.FromFile("ExpectedFinancialReport.pdf"); // Load a mock PDF

        // Act
        pdfGenerator.GenerateFinancialReport("Sample report data");
        var actualPdf = PdfDocument.FromFile("FinancialReport.pdf");

        // Assert
        Assert.AreEqual(actualPdf.ExtractAllText(), expectedPdf.ExtractAllText());
    }
}
$vbLabelText   $csharpLabel

在本測試程式碼中,我們產生一個模擬 PDF(expectedPdf),表示預期的輸出,並將其與 PDFGenerator 產生的 PDF(actualPdf)進行比較。 我們提取了這兩個 PDF 文件的內容,以驗證它們的內容是否相同。

結論

總之,在我們的單元測試過程中,利用 MOQ 和IronPDF ,可以讓我們全面驗證軟體應用程式的行為。 MOQ 使我們能夠隔離特定的程式碼元件、控制依賴關係並模擬複雜的場景,從而使我們能夠編寫有針對性且可靠的測試。

同時, IronPDF透過促進 PDF 文件的產生和操作,增強了我們的測試能力,確保我們與 PDF 相關的功能得到徹底檢驗。 透過將這些工具整合到我們的測試工具包中,我們可以自信地開發出強大且高品質的軟體,滿足功能和效能方面的要求。 將強大的單元測試與 MOQ 和 PDF 驗證相結合,並使用IronPDF進行驗證,顯著提高了我們應用程式的整體品質和可靠性。

值得一提的是, IronPDF提供免費試用版,供使用者測試其各項功能。 如果您覺得符合您的需求,您可以選擇購買商業許可證,這樣您就可以繼續在您的專案中使用 IronPDF 的功能,並享受授權版本帶來的所有優勢和支持,從而確保將 PDF 相關功能順利整合到您的應用程式中。

常見問題解答

Moq 如何增強 C# 中的單元測試?

Moq 增強 C# 中的單元測試,允許開發人員創建模擬對象,這些對象模擬真實對象的行為。這有助於隔離開發人員希望測試的特定代碼組件,確保更準確和專注的測試結果。

Moq 的主要功能是什麼?

Moq 提供設置期望的流暢介面,強類型可減少運行時錯誤,並支持嚴格和寬鬆的模擬,使其成為 C# 應用中的一個有效的單元測試工具。

如何將 IronPDF 集成到 C# 項目中以生成 PDF?

要將 IronPDF 集成到 C# 項目中,可以使用 NuGet 套件管理器控制台並運行命令 Install-Package IronPDF。這將添加生成和操作 PDF 所需的依賴項。

在單元測試中使用模擬 PDF 的目的何在?

模擬 PDF 在單元測試中用於模擬涉及 PDF 文件的真實場景。這允許開發人員測試 PDF 生成和操作功能,確保他們的應用正確處理 PDF。

IronPDF 可以用於商業應用程序嗎?

是的,IronPDF 提供商業許可選項,允許開發人員在商業應用中使用其全方位的 PDF 功能,由許可版本提供的支持和能力。

如何在單元測試中同時使用 Moq 和 IronPDF?

Moq 可以用於模擬代碼中的依賴項,而 IronPDF 可以用於生成和操作 PDF。它們結合使用能夠讓開發人員編寫可靠的測試,確保代碼邏輯和與 PDF 相關的功能的質量。

Moq 在測試 C# 中的依賴交互中起什麼作用?

Moq 幫助測試依賴交互,允許開發人員創建接口的模擬實現,例如 `IHostBank` 和 `IHSMModule`。這允許您模擬各種場景並驗證代碼如預期地與依賴交互。

Moq 如何處理嚴格驗證和寬鬆驗證?

Moq 支持嚴格驗證和寬鬆驗證。嚴格驗證要求滿足所有期望,對於精確測試非常有用。寬鬆驗證則更靈活,允許只驗證感興趣的交互,在複雜系統中很有幫助。

Jacob Mellor, Team Iron 首席技術官
首席技術官

Jacob Mellor是Iron Software的首席技術官,也是開創C# PDF技術的前瞻性工程師。作為Iron Software核心代碼庫的原始開發者,他自公司成立以來就塑造了公司的產品架構,並與CEO Cameron Rimington將公司轉型為服務NASA、Tesla以及全球政府機構的50多人公司。

Jacob擁有曼徹斯特大學土木工程一級榮譽學士學位(1998年–2001年)。他於1999年在倫敦開立首家軟體公司,並於2005年建立了他的第一個.NET組件,專注於解決Microsoft生態系統中的複雜問題。

他的旗艦作品IronPDF和Iron Suite .NET程式庫全球已獲得超過3000萬次NuGet安裝,他的基礎代碼不斷在全球各地驅動開發者工具。擁有25年以上的商業經驗和41年的編碼專業知識,Jacob仍然專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me