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
Totally new to typemock and with only a few months c# experience so I'm not even sure if what I'm trying to do can be done. Some advice would definitely be appreciated :)

I would like to be able to populate a datacontext database with data from an xml file for testing purposes. The code I have unsuccessfully tried is below which may help understand my approach:

Mock sdc = MockManager.Mock(typeof(ServerDataContext));
ServerDataContext dc1 = new ServerDataContext();

XDocument xd = XDocument.Load(@"c:xmlfile.xml");

var cs = from post in xd.Descendants("customers")
select new customer
{
id = Int32.Parse(post.Element("id").Value)
oh_id = Int32.Parse(post.Element("oh_id").Value)
};

var oh = from post in xd.Descendants("order_headers")
select new order_header
{
id = Int32.Parse(post.Element("id").Value)
ol_id = Int32.Parse(post.Element("ol_id).Value)
};

var ol = from post in xd.Descendants("orderlines")
select new orderline
{
id = Int32.Parse(post.Element("id").Value)
};

dc1.customers.InsertAllOnSubmit(cs);
dc1.orderlines.InsertAllOnSubmit(ol);
dc1.order_headers.InsertAllOnSubmit(oh);

This obviously fails because the mocked datacontext has not been initialized with empty tables but with null values. Is there someway of mocking the datacontext and initializing the tables? Or is there someway of mocking a table? I don't really want to have to rely on a connection to an empty database.

I have read articles about using lists to fake return values from specific queries but the problem I have with this is that I return a customer which has joins to order headers which has joins to order lines which can't be represented in a list.

Any suggestions greatfully appreciated!
asked by manx (640 points)

4 Answers

0 votes
Hi Manx and welcome to our forum 8)
There are few issues here:

1. First what are you trying to test? This should be expressed by some kind of an assert statement at the end of test. Most of the times you'll want to use one assert per test which means you are testing one thing each test.

2. You should put some kind of expectation on your mocked/faked instance.
When you write:
Mock sdc = MockManager.Mock(typeof(ServerDataContext)); 

You are just saying "fake the next time the constructor for ServerDataContext is called". This should be followed by sdc.ExpectXXX ... method
But before I'll continue in this rout I would like to get to point 3

3. I would strongly recommend you to use the Arrange Act Assert API
See the first tutorial here:
Using the AAA API will let you write shorter tests while enjoying the benefits of strong typing and the help of IntelliSens.

4. And now to the point:
From the code you posted (Again it's hard to understand as there is no Assert)
it seems like you are trying to test the ServerDataContext. In that case maybe you'll want to fake the XDocument? (Usually you don't want to fake the class under test)

Please let me know if that's correct and I'll try to help you out.
answered by ohad (35.5k points)
0 votes
Hi Ohad, thanks for the welcome!

There are a number of tests that I need to perform which are all data dependent. I need to have a set of control data on the database which I can then use to drive the tests. I could do this by having a physical test database but I don't want to do it this way. I am hoping to have a number of xml files which I can use to prep the database to test different scenarios. For example I will have some orders and some orderlines and then I will call an out of stock method which would return a number of products for that order which were out of stock, so I guess I would be doing something like:

List<product> expected = a list of out of stock products for an order
List<product> actual = CheckStock(dataContext, orderNumber)
Assert.AreEqual(expected, actual)

But to do this the way I am trying to do it I need to be able to populate a dataContext with my test data.

I'm not trying to test the dataContext I'm trying to create a fake dataContext populated with test data.

Hope this explains better!
answered by manx (640 points)
0 votes
Hi Manx,

It seems you want to check your queries and validate them with a predetermined database.
If this is indeed what you are trying to do perhaps you should create a test database and populate it with data and then check that your queries return the correct response.

Mocking framework (Isolator) can help you do one of the following:
1. Create fake instance of an object
2. Set behavior on an object
3. Verify certain method was called.

As a rule of the thumb when testing queries to database you should test using the database. The business logic that uses the result of the queries should be tested using fake objects in order to isolated the tested logic without the database dependency.
answered by dhelper (11.9k points)
0 votes
If I'm right, you're using LINQ to SQL. And it's extremely hard to Isolate the datacontext and/or LINQ to SQL queries.

That's not because of Typemock Isolator, but because of the compiler and the objects. For example, your LINQ queries are transformed by the compiler into code that's hardly recognizable if you looked at it after compilation. Also the DataContext and LINQ to SQL entities generated in the .dbml file are so complex, it's hard to do proper Isolation.

I'd suggest you use the Repository pattern for that. After a quick search I find this is quite a good article about it.

You can then Isolate the repository and return a List<Customer> or whatever instead of working with the DataContext. Don't forget to also do integration testing though with a prepared database!
answered by dvdstelt (5.3k points)
...