Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to autowire field in static @BeforeClass?

@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
    }
}

How can I have my service injected already in the static init class?

like image 349
membersound Avatar asked Mar 30 '15 07:03

membersound


4 Answers

With Junit 5 you can do this (@BeforeAll instead of @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
    }
}

By leaving the field it means it can be used in other tests

like image 148
Vladtn Avatar answered Oct 24 '22 06:10

Vladtn


One workaround that I have been using to get this working is to use @Before with a flag to skip it being executed for each testcase

@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;
    }
  }
}
like image 32
Narain Mittal Avatar answered Oct 24 '22 07:10

Narain Mittal


UPD for Spring 2.x versions.

Spring 2.x supports new feature a SpringExtension for Junit 5 Jupiter, where all you have to do is:

  1. Declare your test class with @ExtendWith(SpringExtension.class)

  2. Inject your @BeforeAll (replacement for @BeforeClass in JUnit 5) with the bean

For example:

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

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

}

Assuming you correctly configured JUnit 5 Jupiter with Spring 2.x

More about it here: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-junit-jupiter-extension

like image 11
yeralin Avatar answered Oct 24 '22 07:10

yeralin


It looks to me that you are trying to populate DB before tests.

I would give a try to two options:

  • If you can extract initial scripts to sql file (if that is option for you without using repository bean) you can use this approach and annotate your test with @Sql
  • You can explore DbUnit and here is link to spring dbunit connector which is doing exactly that and helping you populate DB before tests. Here is a github link for integrating between spring test framework and dbunit. After you do that you have @DatabaseSetup and @DatabaseTearDown which will do thing on DB you need

I know that this does not answer how to inject bean in static @BeforeClass but form code it looks it is solving your problem.

Update: I recently run into same problem in my project and dug out this article which helped me and I think it is elegant way of dealing with this type of problem. You can extend SpringJUnit4ClassRunner with listener which can do instance level setup with all your defined beans.

like image 9
Nenad Bozic Avatar answered Oct 24 '22 05:10

Nenad Bozic