chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I am trying to figure out how I would mock a SubSonic query. What I want to do is, be able to substitute in a fake result for the query so that it doesn't go to the database, but I would also like to verify that the different items in the chain that is used to build the query match what I am expecting. For example here is the query I am using:

            IDataReader dr =
            new Select(new string[] 
            { 
                Product.Columns.ProductID,
                Supplier.Columns.CompanyName,
                Category.Columns.CategoryName,
                Product.Columns.ProductName,
                Product.Columns.UnitPrice
            })
            .From<Product>()
            .InnerJoin(Category.CategoryIDColumn, Product.CategoryIDColumn)
            .InnerJoin(Supplier.SupplierIDColumn, Product.SupplierIDColumn)
            .Where(Product.Columns.UnitPrice).IsLessThanOrEqualTo(50)
            .OrderAsc(new string[] { Category.Columns.CategoryName, Product.Columns.ProductName })
            .ExecuteReader();


So I would like to set up TypeMock to return a fake IDataReader when that executes, but I want it to be smart enough to also verify that the query is hitting the right tables, doing the right joins, using the correct where clause, etc.

I have tried a few different ways to do this with Natural Mocks and I am getting no where with it so I was hoping that someone could give me a hint about how the syntax should look.

When I have done stuff like this with other mocking frameworks there has been a ton of work involved with setting up all of the results for all of the different steps in the chain, so if TypeMock has a way to skip all of that, that would be a huge timesaver for me.

Thanks
asked by Kyle2123 (600 points)

1 Answer

0 votes
Hi
I seems to me that your test should look something like this:

[Test]
public void Test()
{
   string fake1 = Product.Columns.ProductID;
   string fake2 = Supplier.Columns.CompanyName;
   string fake3 = Category.Columns.CategoryName;
   string fake4 = Product.Columns.ProductName;
   string fake5 = Product.Columns.UnitPrice;
   TableSchema.TableColumn fakeColumn1 = Category.CategoryIDColumn;
   TableSchema.TableColumn fakeColumn2 = Product.CategoryIDColumn;
   TableSchema.TableColumn fakeColumn3 = Supplier.SupplierIDColumn;
   TableSchema.TableColumn fakeColumn4 = Product.SupplierIDColumn;
   string fakePrice = Product.Columns.UnitPrice;

   using (RecordExpectations rec = new RecordExpectations())
   {
      rec.DefaultBehavior.CheckArguments();
      IDataReader mockReader = RecorderManager.CreateMockedObject<IDataReader>();
      //record more expectations on mockReader...

      System.Data.IDataReader dum = new Select(new string[] {fake1,fake2,fake3,fake4,fake5})
        .From<Product>()
        .InnerJoin(fakeColumn1, fakeColumn2)
        .InnerJoin(fakeColumn3, fakeColumn4)
        .Where(fakePrice).IsLessThanOrEqualTo(50)
        .OrderAsc(new string[] { fake3, fake4 })
        .ExecuteReader();
      rec.Return(mockReader);
   }
   IDataReader dr =
        new Select(new string[]
      {
         Product.Columns.ProductID,
         Supplier.Columns.CompanyName,
         Category.Columns.CategoryName,
         Product.Columns.ProductName,
         Product.Columns.UnitPrice
      })
        .From<Product>()
        .InnerJoin(Category.CategoryIDColumn, Product.CategoryIDColumn)
        .InnerJoin(Supplier.SupplierIDColumn, Product.SupplierIDColumn)
        .Where(Product.Columns.UnitPrice).IsLessThanOrEqualTo(50)
        .OrderAsc(new string[] { Category.Columns.CategoryName, Product.Columns.ProductName })
        .ExecuteReader();             
}



The arguments are created outside the recording block since you don't
want the calls that creates the argument to be mocked.
It maybe a better idea to use constant values for the arguments in the tests. e.g
string fake2 = "SomeCompany";


Calling rec.DefaultBehavior.CheckArguments() makes sure that all arguments are passed as expected.
Hope it helps.
answered by ohad (35.4k points)
...