sql >> Databasteknik >  >> RDS >> Mysql

Mocking insert-fråga till en MySQL-databas med hjälp av Moq

Metoden som testas för närvarande är för hårt kopplad till implementeringsproblem för att göra den enkelt enhetstestbar isolerad. Försök att ta bort dessa implementeringsproblem så att de lätt kan hånas för isolerade tester.

public interface IDbConnectionFactory {
    IDbConnection CreateConnection();
}

Ovanstående anslutningsfabriksabstraktion kan användas för att komma åt andra nödvändiga System.Data abstraktioner av ditt MySql-datalager.

public class MyDataAccessClass {
    private IDbConnectionFactory connectionFactory;

    public MyDataAccessClass(IDbConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    public void Insert(string firstname, string lastname) {
        var query = $"INSERT INTO `sakila`.`actor`(`first_name`,`last_name`) VALUES('" + firstname + "','" + lastname + "')";
        Console.WriteLine(query);
        using(var connection = connectionFactory.CreateConnection() {
            //Creates and returns a MySqlCommand object associated with the MySqlConnection. 
            using(var command = connection.CreateCommand()) {
                command.CommandText = query;
                Console.WriteLine("Established connection");
                connection.Open();
                command.ExecuteNonQuery();
                Console.WriteLine("Insert query succesfully executed.");
                connection.Close();//is not actually necessary as the using statement will make sure to close the connection.
            }
        }
    }
}

Produktionsimplementeringen av fabriken kommer att returnera en faktisk MySqlConnection

public class MySqlConnectionFactory: IDbConnectionFactory {
    public IDbConnection CreateConnection() {
        return new MySqlConnection("connection string");
    }
}

som kan skickas in i datalagret via beroendeinjektion

För att testa hånar du gränssnitten med ditt val av hånande ramverk eller skapar dina egna förfalskningar för att injicera och testa din metod.

[TestClass]
public class DataAccessLayerUnitTest {
    [TestMethod]
    public void TestInsert() {
        //Arrange
        var commandMock = new Mock<IDbCommand>();
        commandMock
            .Setup(m => m.ExecuteNonQuery())
            .Verifiable();

        var connectionMock = new Mock<IDbConnection>();
        connectionMock
            .Setup(m => m.CreateCommand())
            .Returns(commandMock.Object);

        var connectionFactoryMock = new Mock<IDbConnectionFactory>();
        connectionFactoryMock
            .Setup(m => m.CreateConnection())
            .Returns(connectionMock.Object);

        var sut = new MyDataAccessClass(connectionFactoryMock.Object);
        var firstName = "John";
        var lastName = "Doe";

        //Act
        sut.Insert(firstName, lastName);

        //Assert
        commandMock.Verify();
    }
}

Slutligen är det tillrådligt att du använder kommandoparametrar i kommandotexten eftersom att konstruera frågesträngen manuellt öppnar koden för SQL-injektionsattacker.

För att bättre förstå hur du använder Moq, kolla deras snabbstart




  1. Hur man löser ORA-06512 på radnummer

  2. Vad betyder Import Error:Symbol not found:_PQencryptPasswordConn betyder och hur fixar jag det?

  3. Hur tar man bort dubbletter av poster?

  4. Vad är det bästa sättet att lagra html-kod i mysql?