【问题标题】:JUnit Contract Testing with Suites使用套件的 JUnit 合同测试
【发布时间】:2016-09-23 08:02:06
【问题描述】:

我有一个定义合同的接口(即Repository),几乎没有实现。接口中的每个方法都代表一个特性,我想在其套件测试类中测试每个特性。

假设UserRepository接口如下:

public interface UserRepository {

    Set<User> search(String query);

    Set<User> findBySomethingSpecific(String criteria1, Integer criteria2);
}

目前,为了确保运行相同的测试用例,我创建了一个抽象测试类,并且我的每个实现都有一个扩展抽象测试类的测试类。

public abstract UserRepositoryTest {

    private UserRepository userRepository;

    @Before
    public void setUp() {
        userRepository = createUserRepository();
    }

    @Test public void aTestForSearch() { ... }
    @Test public void anotherTestForSearch() { ... }

    @Test public void aTestForSomethingSpecific() { ... }
    @Test public void anotherTestForSomethingSpecific() { ... }

    protected abstract UserRepository createUserRepository();
}

//------------------------

public class UserRepositoryImplementationTest extends UserRepositoryTest {

    @Override
    protected UserRepository createUserRepository() {
         return new UserRepositoryImplementation();
    }
}

我想找到一种方法将这个抽象测试类划分为一组小测试,因为测试类很快就会变得不堪重负。我看过测试套件,但我不明白如何通过注入不同的实现来创建套件测试类。

另一方面,我发现了这个question,但我的一些存储库在创建时需要一些逻辑(例如,ConnectionPool 用于 SQL 实现)。我目前使用具有不同Context 类的反模式ServiceLocator 来处理创建,但这是static。这就是为什么我有一个通过实现来测试类的方法,所以我可以创建上下文并在之后注入它。

【问题讨论】:

    标签: java unit-testing junit interface test-suite


    【解决方案1】:

    Whit Junit 4 你可以像这样创建一个套件:

    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;
    
    @RunWith(Suite.class)
    @Suite.SuiteClasses({
      TestFeatureLogin.class,
      TestFeatureLogout.class,
      TestFeatureNavigate.class,
      TestFeatureUpdate.class
    })
    
    /**
     * 
     * This suite will execute TestFeatureLogin,TestFeatureLogout,TestFeatureNavigate and TestFeatureUpdate one after the over.
     * 
     * @Before, @After and @Test are no possible of executing in this class.
     * @BeforeClas and @AfterClass are allowed only.  
     * 
     * */
    public class FeatureTestSuite {
        // the class remains empty of test,although it is possible set up a before class and after class annotations.
        // used only as a holder for the above annotations
    
        @BeforeClass
        static public void beforeClass(){
            System.out.println(FeatureTestSuite.class.toString() + " BeforeClass Method");
        }
    
        @AfterClass
        static public void AfterClass(){
            System.out.println(FeatureTestSuite.class.toString() + " AfterClass Method");
        }   
    }
    

    完整的例子可以在here找到

    您必须考虑的另一件事是 @Test 不是抽象类中单元测试的好习惯。如果您想测试您的实现,请创建扩展抽象类的测试类。

    【讨论】:

    • FeatureTestSuite 如何将依赖项注入其所有套件类?
    • @MiniW 另一种选择是使用 Junit 规则 stackoverflow.com/a/13489506/1371064 和 JUnit 参数。显然,这取决于您要测试的测试类型。在我的案例中,我总是使用 Spring 并在其上下文中注入依赖项。这里有一个例子如何stackoverflow.com/a/14946430/1371064
    猜你喜欢
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2022-08-20
    • 2012-12-04
    • 2020-02-27
    • 2016-08-22
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多