Search code examples
unit-testingmsteststubmicrosoft-fakesshim

How can I stub IDBconnection


I am writting Unit Test for my database connection.

I have following class

Public class A
{
    public IDbConnection _dbConnection;

    public A()
    {
       _dbConnection = new SqlConnection(connectionStringName);
    }

    public int ExecuteNoneQuery(CommandDefination command)
    {
       return _dbConnection.Execute(command);
    }
}

I want to test this class, how I can test with Microsoft Stub/Shim

I have written following code, but it is not working.

[TestMethod]
public void TestMethod1()
{
    StubIDbConnection stubIDbConnection = new StubIDbConnection();
    stubIDbConnection.Execute =(null) => -1;
    var a = new classA();
    int answer = a.ExecuteNoneQuery(null);
    Assert.AreEqual(-1, answer);

 }

Solution

  • The method execute doesn't exist in IDbConnection / SqlConnection. Therefore I assume that you have created a custom interface and class.

    The right way to test your code is to change the code into "code that designed to be a testable":

    public class A
    {
        public IDbConnection _dbConnection;
    
        public A() : this(new SqlConnection()){}
    
        public A(IDbConnection connection)
        {
            _dbConnection = connection;
        }
    }
    

    Now you can inject your fake connection:

    [TestMethod]
    public void TestMethod1()
    {
        StubIDbConnection stubIDbConnection = new StubIDbConnection();
        stubIDbConnection.Execute =(null) => -1;
        var a = new classA(stubIDbConnection);
        int answer = a.ExecuteNoneQuery(null);
        Assert.AreEqual(-1,-1);
    }
    

    If you don't want to change your code. You have to create shim, and then change your test method:

        [TestMethod]
        public void TestMethod1()
        {
            using (ShimsContext.Create())
            {
                System.Data.SqlClient.Fakes.ShimSqlConnection.AllInstances.Execute = 
                (connection, command) =>
                {
                    if (command != null)
                        throw new Exception("command is not null");
    
                    return -1;
                };
    
                var a = new classA();
                int answer = a.ExecuteNoneQuery(null);
                Assert.AreEqual(-1, -1);
            }
        }
    

    Edit

    The problem you've faced occurred because Execute method has several overloads.

    Change your test method to:

        [TestMethod]
        public void TestMethod1()
        {
            using (ShimsContext.Create())
            {
                Dapper.Fakes.ShimSqlMapper.ExecuteIDbConnectionCommandDefinition =
                    (connection, command) =>
                    {
                        //add here params verification...
    
                        return -1;
                    };
    
                var a = new A();
                int answer = a.ExecuteNoneQuery(new CommandDefinition());
                Assert.AreEqual(-1, answer);
            }
        }