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
0 votes
Hello all.

I just downloaded the trial version (enterprise), and wish to begin working with Typemock, to test my code which includes Linq queries.

I saw examples, where you record linq expressions and return lists, like:
var dummyData = new[] {new {Name="fake",City="typemock"},
                       new {Name="another",City="typemock"}};
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
  // Mock Linq
  var queryResult = from c in myCustomerList
      where c.City == "Sarasota"
      select new {c.Name, c.City };
  // return fake results
  recorder.Return(dummyData);
}


Thing is, this doesn't test the query itself. I'm missing out on testing some important code here.

I thought perhaps I could use the magic of Linq which allows me to mock properties, and could perhaps mock a table, and return a canned list, and ultimately run Linq on that object.
so that if I have
public class CustomerDataContext : MyDataContext
{
   public System.Data.Linq.Table<Title> Titles
   {
      get
      {
         return this.GetTable<Title>();
      }
   }
}


I could mock Titles, to return some list like dummyData above.

How could I make this work?
asked by abstone (1.3k points)

6 Answers

0 votes
Hi

I'm not sure I understand what you are trying to do but I'll take
a shot.

In natural mocks all you have to do in order to mock the property is to
call it inside the recording block.
So in our case you need to do this:
Table myCustomTable = SetMyCustomTable();
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
   CustomerDataContext mock = new CustomerDataContext();
   System.Data.Linq.Table dummy = mock.Titles;
   recorder.Return(myCustomTable);
}


As I said I'm not sure if that's what you trying to do so if you need more help on this issue please tell me.
answered by ohad (35.4k points)
0 votes
Hi. I'll try to explain further:
Using the Linq-to-SQL code-generator, I generated CustomerDataContext, which inherits from DataContext.
After dragging the Customer table from my data connections (in the Server explorer), I now have a Customer class. similarly a property was generated in CustomerDataContext, as follows:
public System.Data.Linq.Table<Customer> Customers
{
    get
    {
        return this.GetTable<Customer>();
    }
}


Now, I've got (in a different assemby), the code as follows
public IList<Customer> FetchAllCustomers()
{
     return db.Customers.Where(c => c.Promoted.HasValue).OrderBy(c => c.Promoted).ToList();
}


What I want to do is to substitute the access to the database, and return a mocked customer list, which I create as a List<Customer> with a few values I add during the test.

The test I wrote is:
            ICustomerServicesRepository rep = new CustomerServicesRepository();
            List<Customer> mockCats = new List<Customer>();
            mockCats.Add(new Customer{ ID = 1, Name = "Fake Cat", Promoted = 1 });
            mockCats.Add(new Customer{ ID = 2, Name = "Don't show this Fake Cat", Promoted = 0 });
            mockCats.Add(new Customer{ ID = 3, Name = "Another Fake Cat", Promoted = 2 });

            MockManager.Init();
            MockObject mockDC = MockManager.MockObject(typeof(CustomerServicesDataContext));
            mockDC.ExpectGetAlways("Customers", mockCats);

            IList<Customer> customers = rep.FetchAllCustomers();

            Assert.AreEqual(3, customers.Count);


Unfortunately, I don't get the 3 I generated, but the 6 in the database.
What did I do wrong?

Thanks.
answered by abstone (1.3k points)
0 votes
Hi
It looks like you should use MockManager.Mock() instead of MockManager.MockObject()
Try this:
MockObject mockDC = MockManager.Mock(typeof(CustomerServicesDataContext));


The difference is that MockManager.Mock will mock the NEXT new of the mocked class (as in this case)
MockManager.MockObject creates a new mocked object on the spot.
(This useful when you want to mock an abstract class or an interface)
See more details here

Hope it helps.
answered by ohad (35.4k points)
0 votes
Thanks. I tried, but it still doesn't help.
Here's the updated code:
        [Test]
        public void TestFetchAllCategories()
        {
            ICustomerServicesRepository rep = new CustomerServicesRepository();
            List<Category> mockCats = new List<Category>();
            mockCats.Add(new Category { ID = 1, Name = "Fake Cat", Promoted = 1 });
            mockCats.Add(new Category { ID = 2, Name = "Don't show this Fake Cat", Promoted = 0 });
            mockCats.Add(new Category { ID = 3, Name = "Another Fake Cat", Promoted = 2 });

            MockManager.Init();
            Mock mockDC = MockManager.Mock(typeof(CustomerServicesDataContext));
            mockDC.ExpectGetAlways("Categories", mockCats);

            IList<Category> categories = rep.FetchAllCategories();

            Assert.AreEqual(3, categories.Count);
        }


I still get the 6 categories from the DB, rather than the 3 in mockCats.
answered by abstone (1.3k points)
0 votes
Hi
My guess is that the CustomerServicesDataContext object in
CustomerServicesRepository class is created in the first line of the code.
Since the MockManager.Mock() method will mock the next instance this
never happens.
Try to move the mock before that line
So the code should be:
[Test]
public void TestFetchAllCategories()
{
   MockManager.Init();
   Mock mockDC = MockManager.Mock(typeof(CustomerServicesDataContext));
   mockDC.ExpectGetAlways("Categories", mockCats);
   
   ICustomerServicesRepository rep = new CustomerServicesRepository();
   List<Category> mockCats = new List<Category>();
   mockCats.Add(new Category { ID = 1, Name = "Fake Cat", Promoted = 1 });
   mockCats.Add(new Category { ID = 2, Name = "Don't show this Fake Cat", Promoted = 0 });
   mockCats.Add(new Category { ID = 3, Name = "Another Fake Cat", Promoted = 2 });
   
   IList<Category> categories = rep.FetchAllCategories();

   Assert.AreEqual(3, categories.Count);
} 
answered by ohad (35.4k points)
0 votes
Great!!!

Thanks. It works! I think I'm going to use this in my production!
:D :D :D
answered by abstone (1.3k points)
...