locked
Test-Driven Development and Interfaces RRS feed

  • Question

  • Hello!

    I've got this interface called ISet<T> which my ArraySet<T> class implements but right now I've only created the implementation of the interface and my ArraySet code looks like:

    public ArraySet<T> : ISet<T>
    {

    }

    When I try to build ofcourse I get alot of errors that my class is not implementing the interface members. When using Test-Driven Development I should not write any code that my tests isn't testing. to be able to build now I have to write empty methods for all my interface members before I've got tests for them. Is there a good practice for how to do this or should I just write empty methods to implement the interface and then start with the tests?

    Thanks in advance!

    -Martin
    Wednesday, June 21, 2006 8:02 AM

Answers

  • Hello

    The final purpose of TDD is to probe all the lines of code we are implementing. It is suposed you cannot define any method until you have clear the method that will probe it.

    The problem with interfaces is that you have absolutely defined a number of methods inside the class. My advice is to implement the required members in the most basic possible way. For example, if you should have to retrieve a value from a method, insert a simple return statement in the method by the moment. Once you have the tests to verfy it works, then you should change tthat code into something... let's say, more elaborated.

    First, you should have something like this:

    function getEnumerator() as integer
    return 0
    end function

    this will allow you to build and pass the tests. Once you reach the tests that probe this method, you should change the code:

    function getEnumerator() as integer
    dim valueToReturn as integer=0

    ' Some code by here

    return valueToreturn
    end function

     

    Anyway, this is my point of view. And remember you may find another way of TDDing that may different and usefull for your case.

    Hope this is useful

     

    Jesus M

    Wednesday, June 21, 2006 12:35 PM

All replies

  • Hello

    The final purpose of TDD is to probe all the lines of code we are implementing. It is suposed you cannot define any method until you have clear the method that will probe it.

    The problem with interfaces is that you have absolutely defined a number of methods inside the class. My advice is to implement the required members in the most basic possible way. For example, if you should have to retrieve a value from a method, insert a simple return statement in the method by the moment. Once you have the tests to verfy it works, then you should change tthat code into something... let's say, more elaborated.

    First, you should have something like this:

    function getEnumerator() as integer
    return 0
    end function

    this will allow you to build and pass the tests. Once you reach the tests that probe this method, you should change the code:

    function getEnumerator() as integer
    dim valueToReturn as integer=0

    ' Some code by here

    return valueToreturn
    end function

     

    Anyway, this is my point of view. And remember you may find another way of TDDing that may different and usefull for your case.

    Hope this is useful

     

    Jesus M

    Wednesday, June 21, 2006 12:35 PM
  • I agree also with Jesus, althought it doesn't meet the TDD as it says "code the test first", but I think more than return a value, I will follow what VS 2005 does, and throw and exception, this way you can be sure you don't leave any "weak" test.
    Wednesday, June 21, 2006 2:26 PM
  • Hello again!

    Thanks both of you, thats pretty much what I thought about doing. The tips about throwing a NotImplementedException (or whatever the correct exception is) was good too, I'll do that.

    Regards,

    -Martin
    Wednesday, June 21, 2006 8:24 PM
  • I will never implement an interface until I have a defined requirement to create the implementation - and even then I would still code up the tests first and implement the interface to throw exceptions just to get the code to compile (as Luis suggests).

    If I have another production class which uses an interface instance I always use dependency injection for unit testing to inject a mocked instance configured with my expectations - this way I remove the dependency altogether and can quickly and easily configure the mock to behave exactly how I want it to for each test.

    e.g. each method I would usually expect to test 3 things - valid args and an expected result, invalid args, and exception conditions - with a simple implementation of an interface you would need to implement the interface 3 times whereas with a mock you just configure it to behave differently each test.

    I use TypeMock.Net mocking library as it offers some extremely powerful features (some of which fly in the face of pure TDD but are *really* useful for mocking components etc and things like HttpContext). It's not free but you can get a free trial version. If you want a free mocking library but less featured check out NMock

    Good luck and gimme a shout if you want any help with the mocking.

    Tuesday, June 27, 2006 4:24 PM
  • Hello!

    Thanks for answering me. I've not used Mocking anything yet so I don't really understand what it is or the way you work with it. I'm going to read some about it and see if I understand what you mean better after that. Also, I hadn't thought about the 3 test per method thing either, good information, thanks =)

    Regards,

    -Martin
    Wednesday, June 28, 2006 3:58 AM