如何在静态@BeforeClass中自动装配字段?

时间:2015-03-30 07:11:48

标签: java spring junit spring-test

@RunWith(SpringJUnit4ClassRunner.class)
public void ITest {
    @Autowired
    private EntityRepository dao;

    @BeforeClass
    public static void init() {
        dao.save(initialEntity); //not possible as field is not static
    }
}

如何在静态init类中注入我的服务?

6 个答案:

答案 0 :(得分:14)

我一直使用的一个解决方法是使用带有标志的@Before来跳过为每个测试用例执行

@RunWith(SpringJUnit4ClassRunner.class)
public class BaseTest {

@Autowired
private Service1 service1;

@Autowired
private Service2 service2;

private static boolean dataLoaded = false;

@Before
public void setUp() throws Exception {

    if (!dataLoaded) {
        service1.something();
        service2.somethingElse();
        dataLoaded = true;
    }
  }
}

答案 1 :(得分:8)

在我看来,您正试图在测试之前填充数据库。

我会尝试两种选择:

  • 如果您可以将初始脚本提取到sql文件(如果这是您不使用存储库bean的选项),则可以使用this approach并使用@Sql
  • 注释您的测试
  • 您可以探索DbUnit,这里是link to spring dbunit connector,它正是这样做的,并帮助您在测试前填充数据库。这是一个github link,用于在spring测试框架和dbunit之间进行集成。完成此操作后,您将@DatabaseSetup@DatabaseTearDown在您需要的数据库上执行操作

我知道这并没有回答如何在静态@BeforeClass中注入bean,而是形成代码,它看起来正在解决你的问题。

<强>更新 我最近在我的项目中遇到了同样的问题并且挖出this article这对我有帮助,我认为这是处理这类问题的优雅方式。您可以使用侦听器扩展SpringJUnit4ClassRunner,该侦听器可以使用您定义的所有bean进行实例级别设置。

答案 2 :(得分:2)

要回答这个问题,我们应该回顾一下Spring 2.x版本。

如果你想&#34; autowire&#34; @BeforeTest类中的bean可以使用ApplicationContext接口。让我们看一个例子:

@BeforeClass
    public static void init() {
        ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        EntityRepository dao2 = (EntityRepository) context.getBean("dao");
        List<EntityRepository> all = dao2.getAll();
        Assert.assertNotNull(all);
    }

发生了什么:使用ClassPathXmlApplicationContext我们正在实例化application-context.xml文件中包含的所有bean。

使用context.getBean()我们读取指定的bean(它必须与bean的名称匹配!);然后你可以用它来进行初始化。

你应该给豆子另一个名字(dao2!),否则春天正常&#34; autowired&#34;无法在预定义的bean上工作。

作为旁注,如果您的测试扩展AbstractTransactionalJUnit4SpringContextTests,您可以使用executeSqlScript(sqlResourcePath, continueOnError)进行初始化;方法,所以你不依赖于你必须单独测试的类/方法。

答案 3 :(得分:0)

适用于Spring 2.x版本的UPS。

Spring 2.x支持Junit 5 Jupiter的新功能SpringExtension,您要做的就是:

  1. 使用@ExtendWith(SpringExtension.class)

  2. 声明测试类
  3. 用bean注入@BeforeAll(在JUnit 5中替换@BeforeClass

例如:

@ExtendWith(SpringExtension.class)
...
public void ITest {

    @BeforeAll
    public static void init(@Autowired EntityRepository dao) {
        dao.save(initialEntity);
    }

}

假设您已使用Spring 2.x正确配置了JUnit 5 Jupiter

此处有更多相关信息:https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-junit-jupiter-extension

答案 4 :(得分:0)

使用Junit 5,您可以执行此操作(@BeforeAll而不是@BeforeClass)

public void ITest {
    @Autowired
    private EntityRepository dao;

    @BeforeAll
    public static void init(@Autowired EntityRepository dao) {
        dao.save(initialEntity); //possible now as autowired function parameter is used
    }
}

离开字段意味着它可以在其他测试中使用

答案 5 :(得分:0)

如果您只想在测试中使用一些数据库数据,您还可以模拟存储库并使用 @Before 解决方法 Narain Mittal 描述:

@RunWith(SpringJUnit4ClassRunner.class)
public void ITest {
    @MockBean
    private EntityRepository dao;

    @Before
    public static void init() {
        when(dao.save(any())).thenReturn(initialEntity);
    }
}