Java - contract tests

后端 未结 2 1314
温柔的废话
温柔的废话 2021-01-22 06:40

I am trying to write contract tests for some widely used interfaces:

Along the lines of:

public abstract class MyInterfaceContractTest extends TestCase {         


        
相关标签:
2条回答
  • 2021-01-22 07:00

    If I've understood your need correctly, you want to run the same test method or methods with multiple implementations of the same interface.

    I don't know how to do this very nicely in JUnit 3.

    If you're willing to upgrade to JUnit 4, this can be done by using a parametrized test.

    For the simple example of running a single test method on two implementations of an interface, your test code could look something like this:

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    
    import java.util.Arrays;
    import java.util.Collection;
    
    import static junit.framework.Assert.assertEquals;
    
    // Tell JUnit4 to run it as a parametrized test.
    @RunWith(Parameterized.class)
    public class MyInterfaceContractTest {
    
        private MyInterface _toTest;
    
        // Load the test data into your test instance via constructor
        public MyInterfaceContractTest(MyInterface impl) {
            this._toTest = impl;
        }
    
        // Supply the test data, in this example just the two implementations you want to test.
        @Parameterized.Parameters
        public static Collection<Object[]> generateData() {
            return Arrays.asList(new Object[]{new MyInterfaceImpl1()}, new Object[]{new MyInterfaceImpl2()});
        }
    
        @Test
        public void testContract(){
            // assert whatever, using your _toTest field
        }
    }
    

    On running this test, JUnit will run the test twice, calling the constructor with the successive entries in the parameter list.

    If you have more complex things, like different expectations for the different implementations, the data generation could return lists of Object arrays that contain multiple elements, and the constructor would then take a corresponding multiple arguments.

    If you need to reinitialize the object under test between test methods, you might also want to use the trick I described in this related question.

    I believe similar things are possible in TestNG, which might be another choice for your upgrade path.

    0 讨论(0)
  • 2021-01-22 07:07

    Generally the approach would be to use a "testable" subclass of the abstract class to test all the functionality of the abstract class in one test. Then write a separate test for each concrete implementation testing just the methods defined / implemented in the concrete class (don't retest the functionality in the concrete class).

    0 讨论(0)
提交回复
热议问题