为许多不同的配置文件测试一个Spring Test Class

时间:2017-12-14 15:31:54

标签: java spring junit

我正在使用:

  • Spring Framework 4.3.10
  • JUnit 4.12
  • Gradle 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 {

关于@Test方法的代码对于两个测试类都是相同的,违反了DRY原则,这两个测试类之间的唯一区别是jdbc和{{1} }个人资料与其他Hibernate一起工作,内部通过每个development, mysql类变体。

直到这里我有2个测试类,违反了TestXXXActiveProfilesResolver原则,在层次结构中思考我将获得3个。

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

  • DRY
  • jdbc,development,mysql

我已经读过:

但我希望避免通过Hibernate,development,mysqlMaven使用命令,以保持对Gradle类的控制。

1 个答案:

答案 0 :(得分:1)

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

        ...

      }

   }

<强>观察

  • outer class必须为abstract
  • 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无法重复使用,必须为每个重写方法声明