0

I have followed Mocking insert query to a MySQL Database using Moq as a guideline to do moq. In my case, I will do moq with postgesql.

Test case is passed. However, I have a question: why "Update query successfully executed" is shown while postgresql's connection state is closed? Is it as expected result when we do moq? If it's not expected result, what should I do?

Thanks in advance.

Here is Console's result After running this test.

UPDATE DEVICES SET user_id=null WHERE camera_id = 'G41140'

Established connection

State Before open : Closed

State After open : Closed

Update query succesfully executed.

This is a part of my code

   [Test, Order(1)]
  public void UpdateTest()
        {
            //Arrange

            DumpDatabase databaseSetting = new DumpDatabase();
            //Assume, fill the right setting for db
            databaseSetting.Host = "***.***.*.**";
            databaseSetting.Port = "****";
            databaseSetting.Database = "*****";
            databaseSetting.UserName = "******";
            databaseSetting.Password = "***********";

            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 DumpConnection(connectionFactoryMock.Object, databaseSetting);
            // Act
            sut.Update();
            // Assert
            commandMock.Verify();


        }
 public class DumpConnection : IDbConnectionFactory
    {
        DumpDatabase _databaseSetting;

        private IDbConnectionFactory connectionFactory;
        public DumpConnection(IDbConnectionFactory connectionFactory, DumpDatabase databaseSetting)
        {
            this.connectionFactory = connectionFactory;
            this._databaseSetting = databaseSetting;
        }

        public IDbConnection CreateConnection()
        {
            return new NpgsqlConnection("Server=" + _databaseSetting.Host + ";User Id=" + _databaseSetting.UserName + "; " +
  "Password=" + _databaseSetting.Password + ";Database=" + _databaseSetting.Database + ";");
        }

        public void Update()
        {
            string query = "UPDATE DEVICES SET user_id=null WHERE camera_id = 'G41140' ";
            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");
                    Console.WriteLine("State Before open : " + connection.State);
                    connection.Open();
                    Console.WriteLine("State After open : " + connection.State);
                    Console.WriteLine("Update query succesfully executed.");
                }
            }
        }

    }
    public interface IDbConnectionFactory
    {
        IDbConnection CreateConnection();

    }

1 Answer 1

0

This looks right to me. Bear in mind when you mock an object (well, it's interface) you get a mocked version of that object. So when you mock your connection var connectionMock = new Mock<IDbConnection>(); you're no longer dealing with a postgres database connection, you're now dealing with your mocked version. So Connection.State is not the connection state of your database, because you're not actually connecting to your database. You're just pretending to for the sake of the test, and in this particular test you're just confirming that the ExecuteNonQuery got called (which is was originally, you seem to have changed the code since then so it no longer is).

Connection.Open() doesnt' do anything, because you're calling it on the mocked connection and haven't configured it to do anything.

Sign up to request clarification or add additional context in comments.

6 Comments

So my test case is work properly right ?. If it is as expected, i will continue to do the same thing with other query [eg. delete,insert,drop etc.]
How can i check my ExecuteNonQuery() is work properly ?. Since my code just checking ExecuteNonQuery is called. Because it seem like i have to clone db from real db before doing an execution on clone db instead of real one in postgresql for verifying/validate my query.
What you're talking about is an integration test. Rather than mock your database, you want to connect to a real version of the database, run the command and then check the results. You generally use mocking to unit test, where you want to just test a specific method, not the things it calls (i.e., when I call Update, does it execute the query?). When you want to test the things that the method is calling, that's an integration test because you're testing the integration of dependancies (i.e., when I call Update, does it update the database correctly). Short version, don't mock to test the exec
So i don't have to use moq anymore right ?. what i have to do is running query on clone db instead of real one. Thus, my test will not affect to real db when i run nunit. When i have done this ,so it is called "integration test" right ?
There's dozens of ways to do integration testing with a database. That would be one. I'm not that familiar with postgres, but with sqlserver I can create an inmemory db that I populate with test data that gets setup/torn down for each test fixture. You could point at a valid db but create test data that you clean up afterwards (not a great idea if you intend to point at prod, but ok for dev/uat usually). Lots of options. It's probably worth reading up on integration testing databases and considering what works best for you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.