Saltar al pie de página
.NET AYUDA

Moq C# (Cómo funciona para desarrolladores)

En el mundo del desarrollo de software, la prueba es un proceso indispensable. Garantiza que tu código funcione como se espera y ayuda a detectar errores antes de que lleguen a producción. Un aspecto vital de las pruebas es el mock, y cuando se trata de pruebas en C#, MOQ es una herramienta poderosa en el arsenal de un desarrollador. Proporciona soporte para expresiones lambda. MOQ, abreviatura de "Mock Object Framework for .NET", simplifica el proceso de creación de objetos mock para pruebas unitarias. En este artículo, profundizaremos en MOQ en C#.

¿Qué es MOQ?

MOQ - Mocking Framework for .NET es un marco de mocking para aplicaciones .NET que permite a los desarrolladores crear objetos mock de manera rápida y eficiente. Los objetos mock simulan el comportamiento de objetos reales en tu aplicación, facilitando el aislamiento y prueba de partes específicas de tu código. MOQ simplifica el proceso de creación y trabajo con estos objetos mock.

Características principales de MOQ

  • Interfaz Fluida: MOQ proporciona una API fluida y expresiva para configurar expectativas y verificaciones. Esto hace que tu código de prueba sea más legible y fácil de entender.
  • Tipado Fuerte: MOQ aprovecha las características del lenguaje C# para proporcionar tipado fuerte y soporte IntelliSense al definir mocks y expectativas. Esto reduce las posibilidades de errores en tiempo de ejecución en tus pruebas.
  • Mocking Suelto: MOQ soporta tanto mocking estricto como suelto. El mocking suelto te permite crear objetos mock que respondan a cualquier llamada de método, mientras que el mocking estricto sólo permite que se llamen los métodos esperados.
  • Comportamiento Verificable: MOQ te permite verificar que los métodos específicos en tus objetos mock se llamaron con los argumentos esperados y en el orden correcto.
  • Devoluciones y Callbacks: Puedes definir devoluciones para ejecutar código personalizado cuando se llama a un método mock y especificar valores de retorno para métodos mock.

Cómo empezar con MOQ

En este tutorial, exploraremos cómo usar MOQ, un marco de mocking popular para C#, para facilitar las pruebas unitarias. Examinaremos un ejemplo donde creamos y probamos un escenario simple de transacción en cajero automático usando MOQ para mockear dependencias.

Crear un nuevo proyecto C

Sigue los siguientes pasos para crear un nuevo proyecto:

  1. Abre Visual Studio, ve a "Archivo" > "Nuevo" > "Proyecto...".
  2. Elige una plantilla de proyecto, configura los ajustes y haz clic en "Crear".

Moq C# (Cómo Funciona Para Desarrolladores) Figura 1 - Crea una nueva aplicación de consola en Visual Studio 2022

Supongamos que estás desarrollando software para un cajero automático (ATM), y necesitas probar la funcionalidad de autenticación y retiro. El ATM depende de dos interfaces: IHostBank y IHSMModule. Queremos probar la clase ATMCashWithdrawal, que representa la funcionalidad de retiro de efectivo del ATM.

Crea dos interfaces, IHostBank y IHSMModule, que representan las dependencias del sistema ATM. Define métodos relevantes como AuthenticateAmount y ValidatePIN.

// 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

Crea la clase ATMCashWithdrawal, que utiliza las dependencias mencionadas anteriormente para realizar operaciones del ATM. En esta clase, implementarás un método específico como 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

Crear un proyecto de prueba unitaria

Ahora, vamos a crear pruebas unitarias para la clase ATMCashWithdrawal usando MOQ para mockear las dependencias.

Crea un nuevo proyecto de prueba unitaria en tu solución y llámalo ATMSystem.Tests.

Para agregar un proyecto de prueba NUnit a tu solución de Visual Studio, sigue estos pasos:

  1. Haz clic derecho en la Solución: En el Explorador de Soluciones (normalmente en el lado derecho), haz clic derecho en el nombre de la solución.
  2. Agregar > Nuevo Proyecto: Desde el menú contextual, selecciona "Agregar" y luego "Nuevo Proyecto...".
  3. Crea un Nuevo Proyecto: En el cuadro de diálogo "Agregar Nuevo Proyecto", puedes buscar "NUnit" para encontrar las plantillas de NUnit disponibles. Elige el Proyecto de Prueba NUnit como se muestra a continuación.

Moq C# (Cómo Funciona Para Desarrolladores) Figura 2 - Agrega un nuevo Proyecto de Prueba NUnit en tu solución.

  1. Configura el Proyecto: Configura la configuración del proyecto según sea necesario, incluido el nombre y ubicación del proyecto.
  2. Haz clic en OK: Haz clic en el botón "Crear" o "OK" para agregar el proyecto de prueba NUnit a tu solución.

Ahora, tienes un proyecto de prueba NUnit separado dentro de tu solución donde puedes escribir y administrar tus pruebas unitarias. También puedes agregar referencias a los proyectos que deseas probar y comenzar a escribir tus casos de prueba NUnit en este proyecto.

Para comenzar a usar MOQ en el proyecto de prueba, necesitarás agregar el paquete NuGet de MOQ a tu solución. Puedes hacerlo usando el Administrador de Paquetes NuGet en Visual Studio o ejecutando el siguiente comando en la Consola del Administrador de Paquetes:

Install-Package Moq

Este comando instalará el paquete y agregará todas las dependencias necesarias al proyecto.

Escribe pruebas unitarias usando NUnit y MOQ para mockear las dependencias (IHostBank y IHSMModule) de la clase ATMCashWithdrawal.

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

En este código de prueba, estamos usando MOQ para crear objetos mock para IHSMModule y IHostBank y especificar su comportamiento cuando se llaman durante la prueba.

En el ejemplo de código anterior, hemos demostrado el concepto de mockear objetos usando MOQ en C#. Creamos objetos mock para las interfaces IHSMModule y IHostBank, simulando su comportamiento durante las pruebas unitarias. Esto nos permite aislar y probar a fondo la clase ATMCashWithdrawal controlando las respuestas de estos objetos mock. A través de la utilización de mock, podemos garantizar que nuestro código interactúe correctamente con estas dependencias, haciendo nuestras pruebas enfocadas, predecibles y efectivas en identificar problemas dentro de la unidad específica de código bajo examen. Esta práctica mejora la confiabilidad general, mantenibilidad y calidad del código de prueba.

Paso 3 Ejecutar las pruebas

  1. Compila tu solución para asegurarte de que todo esté actualizado.
  2. Abre el Explorador de Pruebas en Visual Studio (Prueba > Explorador de Pruebas).
  3. Haz clic en el botón "Ejecutar Todo" en el Explorador de Pruebas para ejecutar tus pruebas unitarias.
  4. Revisa los resultados de las pruebas. Deberías ver la prueba que escribiste (WithdrawAmount_ValidTransaction_ReturnsTrue) pasar.

Moq C# (Cómo Funciona Para Desarrolladores) Figura 3 - Para ejecutar las Pruebas, primero deberás compilar la solución. Después de una compilación exitosa, abre el Explorador de Pruebas en Visual Studio y haz clic en el botón Ejecutar Todo para iniciar la ejecución de tus pruebas unitarias.

De esta manera, podemos aislar el código que queremos probar y asegurar que se comporte como se espera bajo varios escenarios al mockear efectivamente las dependencias. Esta práctica mejora la confiabilidad y mantenibilidad de tu software, haciendo más fácil identificar y corregir problemas temprano en el proceso de desarrollo.

Presentando IronPDF

Documentación de IronPDF y Vista General de Características es una poderosa biblioteca de C# que permite a los desarrolladores trabajar con documentos PDF dentro de sus aplicaciones. Ofrece una amplia gama de funciones, incluyendo la creación, modificación y conversión de archivos PDF desde varias fuentes, como HTML, imágenes y PDFs existentes. Cuando se combina con el concepto de mockear objetos discutido en el tutorial anterior, IronPDF puede ser una herramienta valiosa para generar y manipular documentos PDF en tus pruebas unitarias.

La característica principal de IronPDF es su función de Conversión de HTML a PDF, asegurando que los diseños y estilos estén intactos. Convierte contenido web en PDFs, haciéndolo perfecto para reportes, facturas y documentaciones. Domina PDFs con IronPDF, biblioteca C# que simplifica el trabajo con PDFs.

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

Por ejemplo, si tienes un proyecto que involucra la generación o procesamiento de PDF, puedes usar IronPDF para crear documentos PDF mock que imiten escenarios del mundo real. Esto puede ser particularmente útil para probar y validar cómo tu código interactúa con archivos PDF. Puedes generar PDFs mock con contenido, diseños y propiedades específicas, y luego usarlos como fixtures de prueba para asegurar que tu código produce las salidas de PDF deseadas o maneja correctamente las operaciones relacionadas con PDF.

Crear objetos simulados para generar PDF

Supongamos que estás desarrollando una aplicación que genera reportes financieros, y estos reportes deben ser guardados y distribuidos como documentos PDF. En este escenario, podrías querer probar la generación de PDF y asegurar que el contenido y formato sean correctos.

Primero, necesitamos agregar IronPDF a nuestro proyecto. Escribe el siguiente comando en la Consola del Administrador de Paquetes NuGet para instalar IronPDF.

Install-Package IronPdf

Este comando instalará y agregará las dependencias necesarias a nuestro proyecto.

Así es como IronPDF puede incorporarse en el proceso de prueba unitaria:

Generación de PDF simulados

Puedes usar IronPDF para crear documentos PDF mock con contenido y estilos específicos para imitar reportes financieros reales. Estos PDFs mock pueden servir como fixtures de prueba para tus pruebas unitarias, como se muestra en el siguiente fragmento de código:

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

Pruebas unitarias con PDF simulados

Escribiremos pruebas para usar IronPDF para generar PDFs mock que representen varios escenarios de reporte. Entonces, compararemos los PDFs reales generados por nuestro código con estos PDFs mock para asegurar que el contenido, formato y estructura son los esperados.

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

En este código de prueba, generamos un PDF mock (expectedPdf) que representa la salida esperada y lo comparamos con el PDF (actualPdf) generado por el PDFGenerator. Hemos extraído el contenido de ambos PDFs para verificar si tienen el mismo contenido.

Conclusión

En conclusión, aprovechar MOQ, junto con IronPDF en nuestro proceso de prueba unitaria, nos permite verificar exhaustivamente el comportamiento de nuestras aplicaciones de software. MOQ nos permite aislar componentes específicos de código, controlar dependencias y simular escenarios complejos, permitiéndonos escribir pruebas enfocadas y confiables.

Mientras tanto, IronPDF mejora nuestras capacidades de prueba al facilitar la generación y manipulación de documentos PDF, asegurando que nuestras funcionalidades relacionadas con PDF sean examinadas a fondo. Al integrar estas herramientas en nuestro kit de pruebas, podemos desarrollar software robusto y de alta calidad con confianza, que cumpla con las demandas tanto de funcionalidad como de rendimiento. Esta combinación de pruebas unitarias robustas con MOQ y validación de PDF con IronPDF contribuye significativamente a la calidad y fiabilidad general de nuestras aplicaciones.

Vale la pena señalar que IronPDF ofrece una prueba gratuita para probar sus características. Si encuentras que satisface tus necesidades, tienes la opción de comprar una licencia comercial que te permite continuar utilizando las capacidades de IronPDF en tus proyectos con la ventaja y el soporte completo que vienen con una versión con licencia, asegurando la integración suave de funcionalidades relacionadas con PDF en tus aplicaciones.

Preguntas Frecuentes

¿Cómo puede Moq mejorar las pruebas unitarias en C#?

Moq mejora las pruebas unitarias en C# permitiendo a los desarrolladores crear objetos simulados que imitan el comportamiento de objetos reales. Esto ayuda a aislar los componentes de código específicos que los desarrolladores desean probar, asegurando resultados de prueba más precisos y enfocados.

¿Cuáles son las características principales de Moq?

Moq ofrece una interfaz fluida para establecer expectativas, tipado fuerte para reducir errores en tiempo de ejecución, y soporta tanto el simulacro estricto como el flexible, haciendo que sea una herramienta efectiva para pruebas unitarias en aplicaciones C#.

¿Cómo puedo integrar IronPDF en un proyecto C# para la generación de PDF?

Para integrar IronPDF en un proyecto C#, puedes usar la Consola del Administrador de Paquetes NuGet y ejecutar el comando Install-Package IronPdf. Esto añade las dependencias necesarias para generar y manipular PDFs dentro de tu aplicación.

¿Cuál es el propósito de usar PDFs simulados en pruebas unitarias?

Los PDFs simulados se utilizan en pruebas unitarias para simular escenarios del mundo real que involucran documentos PDF. Esto permite a los desarrolladores probar funcionalidades de generación y manipulación de PDF, asegurando que sus aplicaciones manejen los PDF correctamente.

¿Puede IronPDF ser utilizado para aplicaciones comerciales?

Sí, IronPDF ofrece opciones de licencia comercial que permiten a los desarrolladores usar su gama completa de funcionalidades de PDF en aplicaciones comerciales, con el soporte y las capacidades proporcionadas por la versión licenciada.

¿Cómo pueden Moq e IronPDF ser usados juntos en pruebas unitarias?

Moq puede ser utilizado para simular dependencias en tu código mientras que IronPDF puede ser usado para generar y manipular PDFs. Juntos, permiten a los desarrolladores escribir pruebas fiables que aseguren la calidad tanto de la lógica del código como de las funcionalidades relacionadas con PDF.

¿Qué papel juega Moq en la prueba de interacciones de dependencias en C#?

Moq ayuda en la prueba de interacciones de dependencias permitiendo a los desarrolladores crear implementaciones simuladas de interfaces, tales como `IHostBank` y `IHSMModule`. Esto te permite simular varios escenarios y verificar que tu código interactúa con las dependencias como se espera.

¿Cómo maneja Moq el simulacro estricto y flexible?

Moq soporta tanto el simulacro estricto como el flexible. El simulacro estricto requiere que se cumplan todas las expectativas, lo cual es útil para pruebas precisas. El simulacro flexible es más flexible, permitiendo la verificación sólo de las interacciones de interés, lo que puede ser útil en sistemas complejos.

Jacob Mellor, Director de Tecnología @ Team Iron
Director de Tecnología

Jacob Mellor es Director de Tecnología en Iron Software y un ingeniero visionario que lidera la tecnología PDF en C#. Como el desarrollador original detrás de la base de código central de Iron Software, ha moldeado la arquitectura de productos de la compañía desde ...

Leer más