开发者

Enforce jUnit tests cover the whole interface

How can I enforce that my test class covers a particular interface?

Also is there a convention for writing overloaded test methods, so the names are consistent (my current technique is something like: methodName + parameter1Type + parameter2Type + ...)?

I'm hoping the second question will be covered/avoided if there is a good way to do the first.


My issue is I have classes which implement a number of interfaces. Since I'm testing Spring injected service classes, everything has at least one interface.

Anyways say I have a class that implements:

public interface MyInterface{
    int doFoo(int input);
    int doBar(int input);
}

Lets say MyInterfaceImpl, implements this interface.

Now my test class will look something like:

import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class MyInterfaceImplTest{
    private MyInterface = new MyInterfaceImpl(); //could inject it...

    @Test
    public void doFooTest(){
       //content of test not relevant
    }

    @Test
    public void doBarTest(){
       //content of test not relevant
    }
}

Now the above isn't to bad in terms of size, but it's hard to know if I've covered all the testing in larger classes, I could have missed one. Also I find 开发者_如何学Goit anyoying to create method names for overloaded methods. I could also add functionality to a class and possibly missed it. If I'm doing TDD this would be nearly impossible but I'd still like to be sure. What I've been tempted to write is...

public class MyInterfaceImplTest implements MyInterface{

And then I'd like to stick @Test in front of each method. Of course this isn't going to work because, well the test needs to put the values in. But using implements lets the IDE add the methods and it enforces that the full interface has been implemented. To be clear I know I am not looking to actually implement the interface in the test, but I think it could speed up development if I could do something like this.


To me this depends on what you mean by "enforce" and "covers a particular interface".

If your interface methods imply certain "contracts" (e.g. java.util.Collection.add() returns true if the receiving collection was modified as the result of the call), that you want to ensure are upheld by implementers of the interface, you can create a Contract Test.

If you want to see that all methods of a test subject are exercised by a particular test class, you can run the test under a code coverage tool like EMMA or Cobertura and ensure the results are to your liking.


You should probably look into parameterized testing. Here is what it would look like with TestNG:

@Test(dataProvider = "dp")
public testInterface(StrategyInterface si) {
  // will be invoked twice, one with each implementation
}

@DataProvider
static public Object[][] dp() {
  return new Object[][] {
    new Object[] { new Strategy1Impl() },
    new Object[] { new Strategy2Impl() },
  };
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜