为许多不同的配置文件集测试一个 Spring 测试类

Man*_*dan 4 java junit spring

我正在与:

  • Spring框架4.3.10
  • 联合单元4.12
  • 摇篮4.3.1

我有这两个测试班

@Transactional
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class})
@ActiveProfiles(resolver=TestJdbcActiveProfilesResolver.class)
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class PersonaServiceImplJdbcTest {


@Transactional
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class})
@ActiveProfiles(resolver=TestHibernateActiveProfilesResolver.class)
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class PersonaServiceImplHibernateTest {
Run Code Online (Sandbox Code Playgroud)

两个测试类的方法代码@Test是相同的,这违反了DRY原则,这两个测试类之间的独特区别是jdbcHibernate配置文件与其他测试类一起工作,例如development, mysql,它在内部通过每个TestXXXActiveProfilesResolver类变体。

到目前为止,我有 2 个测试类,打破了DRY原则,按层次结构思考我将得到 3 个。

如何(如果可能)使用一个测试类,其中每次交互执行两组(或更多)配置文件,例如:

  • jdbc,development,mysql
  • Hibernate,development,mysql

我已经读过:

但我想避免通过Maven或 来使用命令Gradle,它可以通过类来保持控制TestXXXActiveProfilesResolver

Man*_*dan 5

对于JUnit 4最后我做了以下操作(向下滚动):

@Transactional
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class})
//@ActiveProfiles() ... disable
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public abstract class PersonaServiceImplTest {

   ...

   @Autowired
   private Environment environment;

   @Before
   public void setup(){
    logger.info("Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
   }

   //@Test disable
   public void someTest(){

     assertThat(...)

   }

    @ActiveProfiles(resolver=TestJdbcActiveProfilesResolver.class)
    public static class ForJdbc extends PersonaServiceImplTest {

        public ForJdbc(Persona persona){
            super(persona);
        }

        @Test
        @Override
        @Sql(scripts={"classpath:/.../script.sql"})//when be necessary
        public void someTest()(){
            super.someTest()();
        }

      }

    @ActiveProfiles(resolver=TestHibernateActiveProfilesResolver.class)
    public static class ForHibernate extends PersonaServiceImplTest {

        public ForHibernate(Persona persona){
            super(persona);
        }

        @Test
        @Override
        @Sql(scripts={"classpath:/.../script.sql"})//when be necessary
        public void someTest()(){
            super.someTest()();
        }

        ...

      }

   }
Run Code Online (Sandbox Code Playgroud)

观察结果

  • 必须outer classabstract
  • 必须outer class没有@ActiveProfiles声明
  • 有要测试outer class的方法,每个方法都必须没有 声明@Test
  • Environment是可选的,但对于让知道为每个激活的配置文件很有用static nested class,它通过注释为的通用方法@Before
  • 每一个都static nested class必须是public
  • 每个人都static nested class必须延长outer class
  • 每一个都static nested class必须有@ActiveProfiles
  • 每个都static nested class重写每个测试方法,只是用于super调用相应的重写方法
  • 对于每个static nested class测试重写方法,每个 都必须具有@Test.
  • @Sql不能重用,必须为每个重写的方法声明它