コード例 #1
0
        public void OrderByWithModifierTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT suppliers.id AS supplier_id, suppliers.name AS supplier_name FROM suppliers ORDER BY ModifierFunction(supplier_name);");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["supplier_id"]
                .Will(Return.Value("0"));

            Expect.Once.On(mockReader)
                .Get["supplier_name"]
                .Will(Return.Value("Alice & Co."));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectTypeClause("suppliers", typeof(Supplier));
            sqlBuilder.AddFromClause("suppliers");

            LazyDBQueryProvider<Supplier> provider = new LazyDBQueryProvider<Supplier>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Supplier> query = new Query<Supplier>(provider);

            IQueryable<Supplier> suppliers = from supplier in query
                                             orderby supplier.Name
                                             select supplier;

            List<Supplier> suppliersList = suppliers.ToList();

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #2
0
        public void QueryCachingTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT id FROM employees;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Exactly(1).On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["employee_id"]
                .Will(Return.Value("0"));

            Expect.Once.On(mockReader)
                .Get["employee_name"]
                .Will(Return.Value("Alice"));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder builder = new MySQLBuilder();

            // NB: The select clause we're setting here isn't sufficient to instantiate the objects,
            // which have two fields. This doesn't matter here since we are using mock objects
            // anyway, and in practice it will be up to the author of the SQL statements to get details
            // like this right.
            builder.AddSelectClause("id");
            builder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, builder, new Dictionary<string, object>());

            Query<Employee> myQuery = new Query<Employee>(provider);

            List<Employee> resultList = myQuery.ToList();

            Assert.AreEqual(1, resultList.Count);
            Assert.AreEqual(0, resultList[0].ID);
            Assert.AreEqual("Alice", resultList[0].Name);

            // This shouldn't cause any further DB queries, since we've already evaluated this
            // expression once
            resultList = myQuery.ToList();

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #3
0
        public void OrderByDescendingTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT employees.id AS employee_id, employees.name AS employee_name FROM employees ORDER BY employee_name DESC;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            // We return an empty result set from the mock reader. This doesn't matter much, since we
            // verify that the ORDER BY is set in the SQL query executed.

            SQLBuilder builder = new MySQLBuilder();

            builder.AddSelectTypeClause("employees", typeof(Employee));
            builder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, builder, new Dictionary<string, object>());
            Query<Employee> myQuery = new Query<Employee>(provider);

            var orderedResults = from x in myQuery
                                 orderby x.Name descending
                                 select x;

            List<Employee> resultsList = orderedResults.ToList();

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #4
0
        public void OrderBySubMemberTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT products.id AS product_id, products.name AS product_name, suppliers.id AS supplier_id, suppliers.name AS supplier_name FROM products JOIN suppliers ON products.main_supplier = suppliers.id ORDER BY ModifierFunction(supplier_name);");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder builder = new MySQLBuilder();

            builder.AddSelectTypeClause("products", typeof(Product));
            builder.AddSelectTypeClause("suppliers", typeof(Supplier));

            builder.AddFromClause("products");
            builder.AddJoinClause("JOIN", "suppliers", "products.main_supplier = suppliers.id");

            LazyDBQueryProvider<Product> provider = new LazyDBQueryProvider<Product>(() => mockConnection, builder, new Dictionary<string, object>());
            Query<Product> myQuery = new Query<Product>(provider);

            var orderedResults = from x in myQuery
                                 orderby x.MainSupplier.Name
                                 select x;

            List<Product> resultsList = orderedResults.ToList();

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #5
0
        public void OptimisedCountFailureTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();

            /* We will first try to execute the optimised form of the command, which will fail to return
             * any results. This should lead to the default command being executed, which will return
             * a correct result set */
            IDbCommand optimisedMockCommand = mocks.NewMock<IDbCommand>();
            IDataReader optimisedReader = mocks.NewMock<IDataReader>();

            IDbCommand defaultMockCommand = mocks.NewMock<IDbCommand>();

            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(optimisedMockCommand));

            Expect.Once.On(optimisedMockCommand)
                .SetProperty("CommandText").To("SELECT stat FROM pre_calculated_count;");

            Expect.Once.On(optimisedMockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(optimisedReader));

            Expect.Once.On(optimisedReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(optimisedReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            /* NB: We dispose of the mock connection, then we start using it again. In reality, we've called
             * the provider function again, which returns the same value. For more realism, we could have two
             * mocks and have a provider function that successively returns one, then the other */

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(defaultMockCommand));

            Expect.Once.On(defaultMockCommand)
                .SetProperty("CommandText").To("SELECT COUNT(*) AS numrows FROM employees;");

            Expect.Once.On(defaultMockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["numrows"]
                .Will(Return.Value("42"));

            /* You might expect us to call Read() on the reader until it returns false - but actually, in the
             * case of an aggregate function we don't bother doing this. Since we currently don't support
             * GROUP BY, there's never going to be more than one row in an aggregate result set */
            /*Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));*/

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();
            sqlBuilder.AddSelectTypeClause("employees", typeof(Employee));
            sqlBuilder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Employee> query = new Query<Employee>(provider);

            provider.SetOptimisedCountExpression("SELECT stat FROM pre_calculated_count;");

            int count = query.Count();

            Assert.AreEqual(42, count);
            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #6
0
        public void OrderByCastTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT id AS employee_id, name AS employee_name FROM employees ORDER BY employee_name;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["employee_id"]
                .Will(Return.Value("0"));

            Expect.Once.On(mockReader)
                .Get["employee_name"]
                .Will(Return.Value("Alice"));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectClause("id AS employee_id");
            sqlBuilder.AddSelectClause("name AS employee_name");
            sqlBuilder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Employee> query = new Query<Employee>(provider);

            IQueryable<IPerson> people = query.Cast<IPerson>();

            people = from person in people
                     orderby person.Name
                     select person;

            List<IPerson> peopleList = people.ToList();

            Assert.AreEqual(1, peopleList.Count);
            Assert.IsInstanceOf<IPerson>(peopleList[0]);
        }
コード例 #7
0
        public void ExpressionOptimisationTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT stat FROM pre_calculated_count;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Exactly(1).On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["numrows"]
                .Will(Return.Value("42"));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectTypeClause("employees", typeof(Employee));
            sqlBuilder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Employee> query = new Query<Employee>(provider);

            provider.SetOptimisedCountExpression("SELECT stat FROM pre_calculated_count;");

            int count = query.Count();

            Assert.AreEqual(42, count);

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #8
0
        public void MultipleOrderByTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT employees.id AS employee_id, employees.name AS employee_name FROM employees ORDER BY employee_name, employee_id;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["employee_id"]
                .Will(Return.Value("0"));

            Expect.Once.On(mockReader)
                .Get["employee_name"]
                .Will(Return.Value("Alice"));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectTypeClause("employees", typeof(Employee));
            sqlBuilder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Employee> query = new Query<Employee>(provider);

            IQueryable<Employee> employees = from employee in query
                                             orderby employee.Name,
                                                 employee.ID
                                             select employee;

            List<Employee> peopleList = employees.ToList();

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #9
0
        public void CountExpressionTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT COUNT(*) AS numrows FROM employees WHERE  name LIKE '%smith' ;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            // Note that we only call the reader once, rather than iterating through until
            // it returns false. This works fine when we know we have only one result,
            // which will be the case until we implement GroupBy
            /*Expect.Once.On(mockReader)
                  .Method("Read")
                  .Will(Return.Value(false));*/

            Expect.Once.On(mockReader)
                .Get["numrows"]
                .Will(Return.Value(16));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder builder = new MySQLBuilder();

            builder.AddSelectClause("id");
            builder.AddSelectClause("name");
            builder.AddFromClause("employees");
            builder.AddWhereClause("name LIKE '%smith'", ExpressionType.And);

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, builder, new Dictionary<string, object>());
            Query<Employee> myQuery = new Query<Employee>(provider);

            Assert.AreEqual(16, myQuery.Count());

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #10
0
        public void TakeAndCastTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT employees.id AS employee_id, employees.name AS employee_name FROM employees LIMIT 10;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectTypeClause("employees", typeof(Employee));
            sqlBuilder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Employee> query = new Query<Employee>(provider);

            List<IPerson> employeeList = query.Take(10).Cast<IPerson>().ToList();

            // We've already checked that the correct SQL is sent, so no need to check anything
            // further here
        }
コード例 #11
0
        public void SkipTakeTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT id AS employee_id, name AS employee_name FROM employees LIMIT 10, 15;");

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(mockReader)
                .Get["employee_id"]
                .Will(Return.Value("0"));

            Expect.Once.On(mockReader)
                .Get["employee_name"]
                .Will(Return.Value("Alice"));

            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectClause("id AS employee_id");
            sqlBuilder.AddSelectClause("name AS employee_name");
            sqlBuilder.AddFromClause("employees");

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());
            Query<Employee> query = new Query<Employee>(provider);

            List<Employee> employeeList = query.Skip(10).Take(15).ToList();

            Assert.AreEqual(1, employeeList.Count); // Though we asked for 15 results, there was only one returned
            Assert.AreEqual(0, employeeList[0].ID);
            Assert.AreEqual("Alice", employeeList[0].Name);
        }
コード例 #12
0
        public void SetParametersTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand mockCommand = mocks.NewMock<IDbCommand>();
            IDataReader mockReader = mocks.NewMock<IDataReader>();
            IDbDataParameter mockParameter = mocks.NewMock<IDbDataParameter>();
            IDataParameterCollection mockParameterCollection = mocks.NewMock<IDataParameterCollection>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(mockCommand));

            Expect.Once.On(mockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT id, name FROM employees WHERE  name=@name ;");

            Expect.Once.On(mockCommand)
                .Method("CreateParameter")
                .Will(Return.Value(mockParameter));

            Expect.Once.On(mockParameter)
                .SetProperty("ParameterName").To("@name");

            Expect.Once.On(mockParameter)
                .SetProperty("Value").To("smith");

            Expect.Once.On(mockCommand)
                .GetProperty("Parameters")
                .Will(Return.Value(mockParameterCollection));

            Expect.Once.On(mockParameterCollection)
                .Method("Add").With(mockParameter)
                .Will(Return.Value(0));

            Expect.Once.On(mockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(mockReader));

            // We don't return any values, since we don't need to test what we do with
            // the returned values. The important thing to test is that the parameter
            // methods above get called.
            Expect.Once.On(mockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(mockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectClause("id");
            sqlBuilder.AddSelectClause("name");
            sqlBuilder.AddFromClause("employees");
            sqlBuilder.AddWhereClause("name=@name", ExpressionType.And);

            Dictionary<string, object> parameters = new Dictionary<string, object>();
            parameters["@name"] = "smith";

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, parameters);
            Query<Employee> query = new Query<Employee>(provider);

            List<Employee> employees = query.ToList();

            // The important testing is done in the mock code. Provided the right
            // AddParameter stuff is called, we don't care what happens with the results

            mocks.VerifyAllExpectationsHaveBeenMet();
        }
コード例 #13
0
        public void QueryRepeatabilityTest()
        {
            Mockery mocks = new Mockery();

            IDbConnection mockConnection = mocks.NewMock<IDbConnection>();
            IDbCommand firstMockCommand = mocks.NewMock<IDbCommand>();
            IDbCommand secondMockCommand = mocks.NewMock<IDbCommand>();
            IDataReader firstMockReader = mocks.NewMock<IDataReader>();
            IDataReader secondMockReader = mocks.NewMock<IDataReader>();

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(firstMockCommand));

            Expect.Once.On(firstMockCommand)
                .SetProperty("CommandText").To("SELECT COUNT(*) AS numrows FROM employees WHERE  id=42 ;");

            Expect.Once.On(firstMockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(firstMockReader));

            Expect.Once.On(firstMockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(firstMockReader)
                .Get["numrows"]
                .Will(Return.Value(1));

            Expect.Once.On(firstMockReader)
                .Method("Dispose");

            Expect.Once.On(mockConnection)
                .Method("CreateCommand")
                .Will(Return.Value(secondMockCommand));

            Expect.Once.On(secondMockCommand)
                .SetProperty("CommandText").To("SELECT DISTINCT id AS employee_id, name AS employee_name FROM employees WHERE  id=42 ;");

            Expect.Once.On(secondMockCommand)
                .Method("ExecuteReader")
                .Will(Return.Value(secondMockReader));

            Expect.Once.On(secondMockReader)
                .Method("Read")
                .Will(Return.Value(true));

            Expect.Once.On(secondMockReader)
                .Get["employee_id"]
                .Will(Return.Value(1));

            Expect.Once.On(secondMockReader)
                .Get["employee_name"]
                .Will(Return.Value("Bob"));

            Expect.Once.On(secondMockReader)
                .Method("Read")
                .Will(Return.Value(false));

            Expect.Once.On(secondMockReader)
                .Method("Dispose");

            // NB: We're returning the same connection object twice, so we'll dispose it twice. This
            // isn't really correct, but since these are mock objects nobody will know that they're
            // the same object
            Expect.Exactly(2).On(mockConnection)
                .Method("Dispose");

            SQLBuilder sqlBuilder = new MySQLBuilder();

            sqlBuilder.AddSelectClause("id AS employee_id");
            sqlBuilder.AddSelectClause("name AS employee_name");
            sqlBuilder.AddFromClause("employees");
            sqlBuilder.AddWhereClause("id=42", ExpressionType.And);

            LazyDBQueryProvider<Employee> provider = new LazyDBQueryProvider<Employee>(() => mockConnection, sqlBuilder, new Dictionary<string, object>());

            Query<Employee> query = new Query<Employee>(provider);

            int numEmployees = query.Count();
            Assert.AreEqual(1, numEmployees);

            List<Employee> employees = query.ToList();
        }