Unit Testing ADO.NET Data Services
ADO.NET Data Services enables you to expose data (including, but not limited to, relational data) as REST services. Since it's built on top of WCF, it can be tested utilizing similar techniques, but allow me to elaborate a bit on the subject.
As with WCF, you might be interested in testing one or both tiers:
- The service
- The client
Testing the service is the simplest undertaking, so I'll start with that and return to testing the client in a later post.
Why would you want to unit test an ADO.NET Data Service?
The mainstream scenario for ADO.NET Data Services is to expose a relational database using an ADO.NET Entity Model. Is it relevant to unit test such a service? Perhaps not. It depends on the amount of code you inject into the generated (partial) classes. If the amount of custom code is minimal, it may not make much sense to test simple CRUD operations.
Conversely, if you have a greater degree of custom code, or if you implement an ADO.NET Data Service using non-relational data, it makes a lot of sense.
My loyal readers will probably (correctly) suspect that I would tend to expose a Façade over a Domain Model as a data service, which implies going the non-relational route (even if the underlying data store is, in fact, relational). That is also the context for the rest of this post.
First of all, you should keep in mind that the data service is just a normal class, so you can test much of its functionality by just creating it and start using it:
[TestMethod]
public void ServiceCanReturnRequestedItem()
{
// Fixture setup
int anonymousId = 3;
string expectedText = "Ploeh";
Parent anonymousParent = new Parent();
anonymousParent.Id = anonymousId;
anonymousParent.Text = expectedText;
MyService sut = new MyService();
sut.ParentStore.Add(anonymousParent);
// Exercise system
Parent result = (from p in sut.Parents
where p.Id == anonymousId
select p).Single();
// Verify outcome
Assert.AreEqual<string>(expectedText, result.Text,
"Text");
// Teardown
}
Notice how most of the test just contains code setting up the Fixture by adding the relevant data to the service's underlying data store, while execution and verification is quickly accomplished.
At some point, however, you will probably want to test the service through its REST interface. To do this, you must host the service within the test and then invoke it.
Hosting the service in a test is easy:
[TestMethod]
public void TestCanHostService()
{
// Fixture setup
Uri address = new Uri("https://localhost/MyDataService");
using (DataServiceHost host =
new DataServiceHost(typeof(MyDataService),
new[] { address }))
{
host.Open();
// Exercise system
// ...
// Verify outcome
// ...
// Teardown
}
}
Since the service is exposed through a REST interface, you can use more than one technology to invoke it. The ADO.NET Data Services client API is a natural fit, and I'll cover this in a later post. For now, just imagine that the test above contains client code that invokes the service and verifies the result.
As it turns out, unit testing an ADO.NET Data Service isn't particularly difficult. Unit testing ADO.NET Data Service Clients is a bit more involved, so I'll cover that topic in a separate post. Update: This post is now available here.
Comments
Anonymous
January 14, 2009
In my previous post , I discussed unit testing ADO.NET Data Services and how you can host and test theAnonymous
June 24, 2011
The comment has been removedAnonymous
June 24, 2011
If you must you the HttpContext it's best to hide it behind an interface so that you can replace it with something else for use in all those scenarios where it's not available. IIRC WCF doesn't support/populate HttpContext unless the service is running in ASP.NET Compatibility Mode, so that be something else you can try out...Anonymous
March 20, 2013
I don't see how this actually Initializes the service so I can make calls to it. Particularly, I want to call InitializeService, but I don't know what to pass as a DataServiceConfiguration object. It would be nice to see have a working solution to look at.