春季测试-从测试类创建第一个bean并通过真实代码

时间:2020-02-24 12:12:25

标签: java spring spring-test

问题:如何确保测试类中的bean首先在Spring中创建? 情况: 我有一个在运行时提供的数据源,它是通过jndi获得的。 在编译时,我正在为内存DB创建一个,并将其绑定到jndi名称。问题是首先从实际代码中执行jndi查找。

如何确保首先创建测试DS,然后再执行实际代码中的jndi查找?

找到解决方案后进行编辑。 我找到的解决方案是:

有RepositoryConfig.java和RepositoryTestConfig.java。 在将RepositoryConfig导入RepositoryTestConfig之前。

我更改了方法:

  • 我制作了RepositoryTestConfig来扩展RepositoryConfig
  • 我将DS bean隐藏/覆盖到RepositoryTestConfig
  • 在EntityManager上,我通过自动装配添加了DS

问题得到了100%的解决。

对于DS进行jndi查找,我创建了一个单独的测试来证明该方法,因为现在真正的方法已由DS表单RepositoryConfigTest隐藏/覆盖。

3 个答案:

答案 0 :(得分:0)

您应在所需的程序包上使用@Configuration和自定义@ComponentScan类对其进行配置

答案 1 :(得分:0)

您可以使用@Profile

@Configuration
public class AppConfig {

    @Bean
    @Profile("test")
    public DataSource dataSourceTest() throws NamingException {
        return (DataSource) new JndiTemplate().lookup(env.getProperty("jdbc.test.url"));
    }

    @Bean
    @Profile("!test")
    public DataSource dataSource() throws NamingException {
        return (DataSource) new JndiTemplate().lookup(env.getProperty("jdbc.url"));
    }

}

并从测试类中将活动配置文件设置为“ test”,这是一个示例

@ExtendWith(SpringExtension.class)
@ActiveProfiles({ "test" })
@ContextConfiguration(classes = AppConfig.class) 
public class AppTest {

}

说明

@Bean创建与配置中的配置文件相关联。当“测试”配置文件处于活动状态时,将创建具有属性条目jdbc.test.url的数据源实例,对于其他任何配置文件,将创建具有属性jdbc.url的数据源实例。

注意:您可以将test和prod bean配置分开到不同的类中。共享的代码是为了帮助了解@Profile的用法

答案 2 :(得分:0)

最后找到答案: 基本上有2种方法:

  1. 使用@Profile和@ActiveProfile

  2. 通过真实代码配置类的扩展隐藏真实/覆盖真实DS

1。

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(....)
@EntityScan(basePackages = "...")
public class RepositoryConfig {

    @Value("${ds-jndi-name}")
    private String dataSourceJndiname;


    @Bean("myDs")
    public DataSource dataSource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        return dataSourceLookup.getDataSource(dataSourceJndiname);
    }

.....


}

2

@Configuration
public class RepositoryConfigTest extends RepositoryConfig{

    @Value("${ds-jndi-name}")
    private String dataSourceJndiname;

    @Primary
    @Bean("myDs")
    @SneakyThrows
    public DataSource dataSource() {
        EmbeddedDatabase datasource = new EmbeddedDatabaseBuilder()
                .setType(HSQL)
                .setSeparator(";")
                .addScript("classpath:/inmemorytablesdefinitions.sql")
                .build();
        bindDS(datasource);
        return datasource;
    }
 ......
 }

进入要测试的存储库:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {RepositoryConfigTest.class})
public class AppRepositoryTest {

    private App givenApp;

    @Autowired
    private AppRepository appRepository;

    @Before
    public void setup() {
      ... whatever code
    }

 @Test
    public void shoudReadApp() {
        //given
         .....
        //when
           .......
        //then
        assert ...
    }
   }

现在在测试编译时的上下文中,我们在内存中有DS,在运行时,我们通过jndi查找获得了真实的DS。 由于现在已隐藏了运行时DS,因此需要在+中进行测试的是jndi查找。

这样做的好处是,我们没有被迫处理配置文件的维护。如果您的代码中尚未使用配置文件。