Compartir a través de


Cómo: Escribir una prueba unitaria de base de datos que se ejecute en el ámbito de una transacción individual

Este tema se aplica a:

Visual Studio Ultimate

Visual Studio Premium

Visual Studio 2010 Professional 

Visual Studio Express

El tema es aplicable El tema es aplicable El tema no es aplicable El tema no es aplicable

Puede modificar las pruebas unitarias para que se ejecuten dentro del ámbito de una transacción individual. Si utiliza este enfoque, puede revertir cualquier cambio activado por la prueba una vez finalizada. Los procedimientos siguientes explican la manera de:

  • Crear una transacción en el script de prueba Transact-SQL que usa BEGIN TRANSACTION y ROLLBACK TRANSACTION.

  • Crear una transacción para un método de prueba individual en una clase de prueba.

  • Crear una transacción para todos los métodos de prueba de una clase de prueba determinada.

Requisitos previos

Para algunos procedimientos de este tema, el servicio Coordinador de transacciones distribuidas debe estar en ejecución en el equipo en el que se ejecutan las pruebas unitarias. Para obtener más información, vea el procedimiento al final de este tema.

Para crear una transacción mediante Transact-SQL

Para crear una transacción mediante Transact-SQL

  1. Abra una prueba unitaria en el Diseñador de pruebas unitarias de base de datos.

  2. Especifique el tipo de script para el que desea crear la transacción. Por ejemplo, puede especificar un script de prueba, de ejecución previa a la prueba o de ejecución posterior a la prueba.

  3. Escriba un script de prueba en el editor de Transact-SQL.

  4. Inserte las instrucciones BEGIN TRANSACTION y ROLLBACK TRANSACTION como se indica en este ejemplo sencillo. En el ejemplo se usa una tabla de base de datos que se denomina OrderDetails y contiene 50 filas de datos:

    BEGIN TRANSACTION TestTransaction
    UPDATE "OrderDetails" set Quantity = Quantity + 10
    IF @@ROWCOUNT!=50
    RAISERROR('Row count does not equal 50',16,1)
    ROLLBACK TRANSACTION TestTransaction
    

    Nota

    No puede deshacer una transacción tras ejecutar una instrucción COMMIT TRANSACTION.

    Para obtener más información sobre el funcionamiento de ROLLBACK TRANSACTION con procedimientos almacenados y desencadenadores, vea esta página del sitio web de Microsoft: ROLLBACK TRANSACTION (Transact-SQL).

Para crear una transacción para un método de prueba individual

En este ejemplo se usa una transacción de ambiente al emplear el tipo TransactionScope. De forma predeterminada, las conexiones Execution y Privileged no utilizarán la transacción de ambiente, porque se habrán creado antes de ejecutar el método. SqlConnection tiene un método EnlistTransaction, que asocia una conexión activa a una transacción. Cuando se crea una transacción de ambiente, se registra como la transacción actual y se puede tener acceso a ella a través de la propiedad Current. En este ejemplo, la transacción se revierte cuando se elimina la transacción de ambiente. Si desea confirmar cualquier modificación realizada cuando ejecutó la prueba unitaria, debe llamar al método Complete.

Para crear una transacción para un método de prueba individual

  1. En el Explorador de soluciones, haga clic con el botón secundario en el nodo Referencias en el proyecto de prueba y haga clic en Agregar referencia.

    Aparecerá el cuadro de diálogo Agregar referencia.

  2. Haga clic en la ficha .NET.

  3. En la lista de ensamblados, haga clic en System.Transactions y, a continuación, haga clic en Aceptar.

  4. Abra el archivo de Visual Basic o C# de la prueba unitaria.

  5. Incluya las acciones previas a la prueba y posteriores a la prueba, como se indica en el siguiente ejemplo de código Visual Basic:

        <TestMethod()> _
        Public Sub dbo_InsertTable1Test()
    
            Using ts as New System.Transactions.TransactionScope( System.Transactions.TransactionScopeOption.Required)
                ExecutionContext.Connection.EnlistTransaction(Transaction.Current)
                PrivilegedContext.Connection.EnlistTransaction(Transaction.Current)
    
                Dim testActions As DatabaseTestActions = Me.dbo_InsertTable1TestData
                'Execute the pre-test script
                '
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.PretestAction) Is Nothing), "Executing pre-test script...")
                Dim pretestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PretestAction)
                'Execute the test script
    
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.TestAction) Is Nothing), "Executing test script...")
                Dim testResults() As ExecutionResult = TestService.Execute(ExecutionContext, Me.PrivilegedContext, testActions.TestAction)
    
                'Execute the post-test script
                '
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.PosttestAction) Is Nothing), "Executing post-test script...")
                Dim posttestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PosttestAction)
    
                'Because the transaction is not explicitly committed, it
                'is rolled back when the ambient transaction is 
                'disposed.
                'To commit the transaction, remove the comment delimiter
                'from the following statement:
                'ts.Complete()
    
        End Sub
        Private dbo_InsertTable1TestData As DatabaseTestActions
    

    Nota

    Si utiliza Visual Basic, debe agregar Imports System.Transactions (además de Imports Microsoft.VisualStudio.TestTools.UnitTesting, Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting e Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions). Si utiliza Visual C#, debe agregar using System.Transactions (además de las instrucciones using para Microsoft.VisualStudio.TestTools, Microsoft.VisualStudio.TeamSystem.Data.UnitTesting y Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions). También debe agregar a esos ensamblados una referencia al proyecto.

Para crear una transacción para todos los métodos de prueba de una clase de prueba

Para crear una transacción para todos los métodos de prueba de una clase de prueba

  1. Abra el archivo de Visual Basic o C# de la prueba unitaria.

  2. Cree la transacción en TestInitialize y elimínela en TestCleanup, como se muestra en el siguiente ejemplo de código Visual C#:

    TransactionScope _trans;
    
            [TestInitialize()]
            public void Init()
            {
                _trans = new TransactionScope();
                base.InitializeTest();
            }
    
            [TestCleanup()]
            public void Cleanup()
            {
                base.CleanupTest();
                _trans.Dispose();
            }
    
            [TestMethod()]
            public void TransactedTest()
            {
                DatabaseTestActions testActions = this.DatabaseTestMethod1Data;
                // Execute the pre-test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.PretestAction != null), "Executing pre-test script...");
                ExecutionResult[] pretestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PretestAction);
                // Execute the test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.TestAction != null), "Executing test script...");
                ExecutionResult[] testResults = TestService.Execute(this.ExecutionContext, this.PrivilegedContext, testActions.TestAction);
                // Execute the post-test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.PosttestAction != null), "Executing post-test script...");
                ExecutionResult[] posttestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PosttestAction);
    
            }
    

Para iniciar el servicio Coordinador de transacciones distribuidas

Algunos procedimientos de este tema usan los tipos del ensamblado System.Transactions. Antes de seguir estos procedimientos, debe asegurarse de que el servicio Coordinador de transacciones distribuidas está en ejecución en el equipo donde ejecuta las pruebas unitarias. De lo contrario, se produce un error en las pruebas y aparece el mensaje de error siguiente: "El método de prueba nombreDeProyecto.nombreDePrueba.nombreDeMétodo produjo la excepción: System.Data.SqlClient.SqlException: MSDTC en el servidor 'nombreDeEquipo' no está disponible".

Para iniciar el servicio Coordinador de transacciones distribuidas

  1. Abra el Panel de control.

  2. En el Panel de control, abra Herramientas administrativas.

  3. En Herramientas administrativas, abra Servicios.

  4. En el recuadro Servicios, haga clic con el botón secundario en el servicio Coordinador de transacciones distribuidas y haga clic en Iniciar.

    El estado del servicio debería actualizarse a Iniciado. Ahora debería ser posible ejecutar pruebas unitarias que utilizan System.Transactions.

Nota importanteImportante

El siguiente error podría producirse aun cuando se haya iniciado el servicio Coordinador de transaccioones distribuidasSystem.Transactions.TransactionManagerCommunicationException: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool. ---> System.Runtime.InteropServices.COMException: The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024). Si se produce, debe configurar elcControlador de transacción distribuida para el acceso de red. Para obtener más información, vea Habilitación del acceso a DTC desde la red.