Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing code using IQueryable

I'm asked to write some unit tests for some functionality, but quite frankly I'm not so sure about the need or usefulness of doing so for this particular piece of code. I'm in no way trying to question the need or usefulness of unit testing in general.

The code in question is very trivial and gets used alot. Basically it's a wrapper around the .Skip() and .Take() extension methods. In my opinion the legitimacy of the methods as a whole is questionable.

The code is basically this:

public IQueryable<T> Page(IQueryable<T> query, int page, int size)
{
    if(query == null) throw new ArgumentNullException("query");
    if(page < 0) throw new ArgumentOutOfRangeException("page"); 
    if(page < 0) throw new ArgumentOutOfRangeException("size"); 

    return query.Skip(page * size).Take(size);
}

Of course I can unit test for the expected exceptions, but what else? Could very well be that I'm missing the point, so what's up with this?

like image 263
fuaaark Avatar asked Jul 29 '26 03:07

fuaaark


2 Answers

You can just hand in a static collection by calling AsQueryable

List<T> dummyData = new List<T>();
//Add data
var result = Page(dummyData.AsQueryable(), 0, 10);
//Perform assertions on result.

If you are in-fact just trying to test that your pagination works correctly.

like image 197
vcsjones Avatar answered Aug 01 '26 12:08

vcsjones


You can test quite a few things here:

  1. Check for proper guards (the exceptions that are thrown when invalid parameters are passed).
  2. Check that Skip was called with the correct parameter.
  3. Check that Take was called with the correct parameter.
  4. Check that Skip was called before Take.

Points 2 - 4 are best tested with a mock. A mocking framework comes in handy here.
This kind of testing is called "interaction-based testing".

You could also use "state-based testing" by calling the method under test with a list with data and check that the returned data is the correct subset.

A test for point 2 could look like this:

public void PageSkipsThePagesBeforeTheRequestedPage()
{
    var sut = new YourClass();
    var queryable = Substitute.For<IQueryable<int>>();

    sut.Page(queryable, 10, 50);

    queryable.Received().Skip(500);
}

This test uses NSubstitute as mocking framework.

like image 45
Daniel Hilgarth Avatar answered Aug 01 '26 12:08

Daniel Hilgarth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!