views:

39

answers:

3

Hi Guys,

Had a quick look here, couldn't find a duplicate (correct me if im wrong).

I've got the following Unit Test for some Paging with LINQ:

    // Arrange.
    const int locationId = 1;
    const LocationType locationType = LocationType.City;
    int pageSize = 10;

    // Act.
    var postsPageOne = PostService.FindAllPostsForLocationPaged<Review>(locationId, locationType, 1, pageSize);
    var postsPageTwo = PostService.FindAllPostsForLocationPaged<Review>(locationId, locationType, 2, pageSize);

    // Assert.
    Assert.IsTrue(postsPageOne.Count > 0);
    Assert.IsTrue(postsPageTwo.Count > 0);
    Assert.AreEqual(postsPageOne.Count, pageSize);
    Assert.AreEqual(postsPageTwo.Count, pageSize);
    CollectionAssert.AllItemsAreNotNull(postsPageOne.ToArray());
    CollectionAssert.AllItemsAreNotNull(postsPageTwo.ToArray());

I want to assert that all items in the collection postsPageOne are different to all the items in the collection postsPageTwo. (seems like the way to test paging)

Any ideas of how I can do that?

A: 

Assuming an Id property on your posts:

!postsPageOne.Select(x => x.Id).Intersect(postsPageTwo.Select(x => x.Id)).Any()

The way I test paging in my integration tests is to request a large, single-page list, and then break it into pages, requesting each page and keeping track of all IDs in the order they're returned. Then I compare the IDs returned in the large list to the IDs returned by the paging calls and make sure they match exactly.

HTH,
Kent

Kent Boogaart
It's better to use `Any()` rather than comparing `Count()` to 0 - that way it can stop as soon as it finds anything. Probably not important for a unit test, but worth knowing in general. (Specific to LINQ to Objects, mind you.)
Jon Skeet
@Jon: thanks, knew I was forgetting something. I've updated my post.
Kent Boogaart
In regards to how to do your tests, i expose the paging via another method on my interface (takes in pageSize, pageNumber). So im trying to test that method - using your example of a "single-page list", i would need to use the other method (non-paged), and break that up - therefore i end up not really testing my original method. If that makes sense, probably not. :)
RPM1984
@RPM: your scenario sounds similar to mine. I just use a large number for pageSize - large enough to accommodate all my test data.
Kent Boogaart
+2  A: 

That doesn't sound like the way to test paging to me. I would test paging by having a known dataset, and checking that each page does contain the data I'd expect it to. Otherwise your code could just make up random data, and so long as it was different, your test would pass.

Use a small page size (e.g. 2 or 3) to keep the amount of data to test nice and small.

Jon Skeet
I agree with your second sentence (checking that each page does contain the data I'd expect it to), i already have that test - this is another test to ensure that each page is unique, is that not a valid test?
RPM1984
@RPM1984: No, I don't think so - because if you're testing that the pages are { "a", "b", "c"} and { "d", "e", "f" } already, do you *really* need to test that "a" isn't any of "d", "e", "f" etc? Doesn't your test data ensure that?
Jon Skeet
I guess your right. Im doing paging with Skip/Take, so really, all im doing is attempting to test the framework. Got your point.
RPM1984
+1  A: 
Assert.IsFalse(postsPageOne.Intersect(postsPageTwo).Any());
Darin Dimitrov