Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TDD - writing tests for a method that iterates / works with collections

As a newcomer to TDD I'm stuggling with writing unit tests that deal with collections. For example at the moment I'm trying to come up with some test scearios to essentially test the following method

int Find(List<T> list, Predicate<T> predicate);

Where the method should return the index of the first item in the list list that matches the predicate predicate. So far the only test cases that I've been able to come up with have been along the lines of

  • When list contains no items - returns -1
  • When list contains 1 item that matches predicate - returns 0
  • When list contains 1 item that doesn't match predicate - returns -1
  • When list contains 2 items both of which match predicate - return 0
  • When list contains 2 items, the first of which match predicate - return 0
  • etc...

As you can see however these test cases are both numerous and don't satisfactorily test the actual behaviour that I actually want. The mathematician in me wants to do some sort of TDD-by-induction

  • When list contains no items - returns -1
  • When list contains N items call predicate on the first item and then recursively call Find on the remaining N-1 items

However this introduces unneccessary recursion. What sort of test cases should I be looking to write in TDD for the above method?


As an aside the method that I am trying to test really is just Find, simply for a specific collection and predicate (which I can independently write test cases for). Surely there should be a way for me to avoid having to write any of the above test cases and instead simply test that the method calls some other Find implementation (e.g. FindIndex) with the correct arguments?

Note that in any case I'd still like to know how I could unit test Find (or another method like it) even if it turns out that in this case I don't need to.

like image 756
Justin Avatar asked Jul 05 '12 13:07

Justin


1 Answers

If find() is working, then it should return the index of the first element that matches the predicate, right?

So you'll need a test for the empty list case, and one for the no-matching elements case, and one for a matching element case. I would find that sufficient. In the course of TDDing find() I might write a special first-element-passes case, which I could fake easily. I would probably write:

emptyListReturnsMinusOne()
singlePassingElementReturnsZero()
noPassingElementsReturnsMinusOne()
PassingElementMidlistReturnsItsIndex()

And expect that sequence would drive my correct implementation.

like image 144
Carl Manaster Avatar answered Oct 06 '22 01:10

Carl Manaster