How to test LINQ queries using Rhino

662 views
Skip to first unread message

Laksh

unread,
Jan 20, 2012, 12:01:24 AM1/20/12
to Rhino.Mocks
I'm using 3.6 version of Rhino. How do i test the following funtion
which has LINQ query

protected override void Execute(int PackageID)
{

// get the package hierarchy from the database
IRepository<Package> repository =
DefaultServiceLocator.Instance.GetInstance<IRepository<Package>>();
var package = repository.GetQuery()
.Where(a => a.PackageID == PackageID)
.Include(a => a.PackageDetails.Select(b =>
b.DocumentTemplate))
.Include(a => a.PackageArea)
.Include(a => a.ReturnDetails)
.FirstOrDefault();

this.Package.Set(package);
}

Patrick Steele

unread,
Jan 20, 2012, 8:18:11 AM1/20/12
to rhino...@googlegroups.com
First off, it looks like you're using a Service Locator. The Service
Locator is generally regarded as an anti-pattern
(http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx)
and you should try and avoid it if possible. Ideally, the
IRepository<Package> would be injected into the class that contains
this method. However, if you're stuck with this, there's still a way
you can test this.

Your method does two things:

1) Runs the LINQ query on the IRepository<Package>
2) Calls the Package.Set() method

For #1, I would create a stub IRepository<Package> and stub the
GetQuery() method to return a set of data that will "exercise" your
LINQ query. In other words, make sure it returns data that will test
both true and false for your Where() condition. And don't forget to
test the possibility that there are no matches and you return null
(these would all be separate tests).

For #2, you have a couple of options. If you can create a mock of
"Package" (if it's a property, it must be virtual), you can verify
that the "Set" method was called with the particular package that you
expected your LINQ query to return. If Package is NOT virtual and you
can't change it, then your test would have to do some kind of
verification after Execute(int PackageID) was called to make a guess
that "Set" was called (perhaps by checking other properties).

Hope this helps.

---
Patrick Steele
http://weblogs.asp.net/psteele

> --
> You received this message because you are subscribed to the Google Groups "Rhino.Mocks" group.
> To post to this group, send email to rhino...@googlegroups.com.
> To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rhinomocks?hl=en.
>

bill richards

unread,
Jan 20, 2012, 10:14:54 AM1/20/12
to Rhino.Mocks
My take on this is as follows:

You don't need to test the LINQ query. What you actually need to test
is the behaviour of the thing you are building. We can take it as read
that LINQ has been thoroughly tested by Microsoft and it does exactly
what it should do how it should do it.

So then the question becomes .... what am I actually trying to test?

Given that I have a thing for executing
When we invoke Execute passing in the id of a known registered package
Then Package should reference the registered Package

Job done ... if the test passes, your LINQ query is correct if it
fails, it is wrong :o)

Laksh

unread,
Jan 20, 2012, 12:21:52 PM1/20/12
to Rhino.Mocks
Well i was looking for actual example. I know what the test supposed
to do. But i don’t know syntactically how do write the test using
Rhino

On Jan 20, 9:14 am, bill richards <bill.richa...@greyskin.co.uk>
wrote:
> >         }- Hide quoted text -
>
> - Show quoted text -

Shawn Neal

unread,
Jan 20, 2012, 12:33:46 PM1/20/12
to rhino...@googlegroups.com
For testing queries in my repositories I write tests that actually hit a real data source, SQL Server etc. I find its easier and more accurate then trying to mock the underlying provider which I generally have no control over. Its best to mock interfaces you control, like your repository.


bill richards

unread,
Jan 20, 2012, 1:43:14 PM1/20/12
to Rhino.Mocks

// Arrange ... Given that I have a thing for executing
var expected = new Package { Id = 23 };
var thingUnderTest = new MyThingUnderTest();

// Act ... When we invoke Execute passing in the id of a known
registered package
thingUnderTest.Execute(expected.Id);
var actual = thingUnderTest.Package;

// Assert ... Then Package should reference the registered Package
Assert.AreEqual(expected, actual);

So there's really no need for mocking even .... but perhaps you will
be running against a real data store or something, in which case you
need to mock your repository (as suggested by others) ... or maybe you
might just change the following

// Act
thingUnderTest.Execute(23);
// Assert
Assert.AreEqual(23, actual.Id);
Reply all
Reply to author
Forward
0 new messages