1

How to test the behavior of the implementations of interface methods in (abstract) classes without having to copy the tests to each class?

I have (abstract) classes that implement multiple interfaces. I know how each interface should behave, and I define this in test methods so that I don't have to manually repeat these tests for each and every implementation of an interface.

I could create for each interface an abstract class with the tests, and have an abstract method CreateSUT() that creates a new instance of the concrete class. But then I'd have to create a new class with the same CreateSUT() implementation for each interface a class implements, as C# does not support multiple inheritance. Is there a better way to do this?

Also note that I also want to test interfaces implemented in abstract classes that have several non-abstract subclasses, complicating the matter slightly.


This question is not about whether I should unit test my interface implementations. Opinions differ and I've decided to do it because I know how the interface implementations are expected to behave (never returning a null value, returning a read-only collection, etc) and putting these tests together makes it much easier for me to test their implementations, however many there may be.

Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
  • Well there are three options 1. don't test Interface - you declined. 2. Test each derived class. 3. Test one derived class only. – gdoron Mar 22 '12 at 22:09
  • I don't really understand what you are saying in the "I could create..." paragraph. You don't have to include the factory method in the interface. Nor do I understand why you are running into a problem with the "lack of multiple inheritance". You still can have a class implementing several interfaces, which seems to be what your case is about. – Tormod Mar 22 '12 at 22:59
  • maybe related: https://stackoverflow.com/questions/10937763/unit-under-test-impl-or-interface – zwcloud May 03 '19 at 14:11

3 Answers3

0

You could create a list to hold instances of all concrete implementations of your interface, then go through each element in that list and assert the invariant in your test.

Depending on your test framework, there should be a way to get actionable feedback when the test fails.

A quick search found me this for nUnit: http://www.nunit.org/index.php?p=testCaseSource&r=2.5.9

buritos
  • 598
  • 2
  • 9
0

Well, I didn't understand why you need this, but you can write static helper class with tests for your interface. E.g.

public static class IFooTests
{
    public static void ShouldDoSomething(this IFoo foo)
    {
        // Assert something
    }
}

Later for every object that implements IFoo interface you can quickly create test methods:

[Test]
public void ShouldDoSomething()
{
    Bar bar = new Bar(); // create and setup your concrete object
    bar.ShouldDoSomething(); // call interface test extension
}
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
-1

You can mock the abstract class with moq or make a interface that implements all your interfaces and then have your abstract class implement your newly created interface then mock the new interface.

Micah Armantrout
  • 6,781
  • 4
  • 40
  • 66