简体   繁体   English

与套件进行JUnit合同测试

[英]JUnit Contract Testing with Suites

I have an interface that defines a contract (ie a Repository ), with few implementations. 我有一个定义契约(即Repository )的接口,几乎没有实现。 Each method in the interface represents a feature, and I would like to test each feature in its suite test class. 接口中的每个方法都代表一个功能,我想测试其套件测试类中的每个功能。

Let's assume a UserRepository interface as follows: 我们假设一个UserRepository接口如下:

public interface UserRepository {

    Set<User> search(String query);

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

At the moment, to ensure I run the same test cases, I create an abstract test class, and each of my implementations have a test class that extends the abstract test class. 目前,为了确保我运行相同的测试用例,我创建了一个抽象测试类,并且我的每个实现都有一个扩展抽象测试类的测试类。

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();
    }
}

I would like to find a way to divide this abstract test class into a set of small tests, because the test class becomes rapidly overwhelmed. 我想找到一种方法将这个抽象测试类划分为一组小测试,因为测试类很快就会被淹没。 I've looked at test suites, but I don't understand how can I create a Suite test class by injecting my different implementations. 我看过测试套件,但我不明白如何通过注入不同的实现来创建Suite测试类。

As a side not, I've found this question , but some of my repositories require some logic at its creation (for instance, ConnectionPool for a SQL implementation). 作为一个方面,我没有找到这个问题 ,但是我的一些存储库在创建时需要一些逻辑(例如,用于SQL实现的ConnectionPool )。 I currently use the anti-pattern ServiceLocator with different Context classes to handle the creation, but this is static . 我目前使用具有不同Context类的反模式ServiceLocator来处理创建,但这是static That's why I had an approach of a test class by implementation, so I can create the context and inject it afterward. 这就是我通过实现获得测试类的方法的原因,因此我可以创建上下文并在之后注入它。

Whit Junit 4 you can create a suite like this: 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");
    }   
}

The complete example could be found here 完整的例子可以在这里找到

Another thing you have to have into account is that @Test is no a good practice of unit testing inside Abstract class. 您必须考虑的另一件事是@Test不是Abstract类中单元测试的好习惯。 If you want to test your implementations create test classes that extend of Abstract class. 如果要测试实现,请创建扩展Abstract类的测试类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM