0

I create Spring ApplicationContext via code like the following:

public static AnnotationConfigWebApplicationContext startContext(String activeProfile,
                              PropertySource<?> propertySource, Class<?>... configs) {
    AnnotationConfigWebApplicationContext result = new AnnotationConfigWebApplicationContext();
    if (propertySource != null) {
        result.getEnvironment().getPropertySources().addLast(propertySource);
    }
    if (activeProfile != null) {
        result.getEnvironment().setActiveProfiles(activeProfile);
    }
    result.register(configs);
    result.refresh();
    return result;
}

In test class I call it like that:

@RunWith(SpringJUnit4ClassRunner.class)
class FunctionalTest {
    private ApplicationContext appContext;

    @BeforeEach
    void init() {
        appContext = Utils.startContext("functionalTest", getPropertySource(), 
                            BaseConfig.class, MyApplication.class, StorageTestConfig.class);
    }
}

It works fine, no problems.

Now I'm trying to do the same but via annotations:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {BaseConfig.class, MyApplication.class, StorageTestConfig.class}, 
                      loader = AnnotationConfigContextLoader.class)
@ActiveProfiles("functionalTest")
@PropertySource(value = "classpath:test-context.properties")
class FunctionalTest {
      @Autowired
      private ApplicationContext applicationContext;
      ...
}

And this doesn't work at all. applicationContext is not autowired, beans from configurations too. Can you please say me that possibly I do wrong?

Why I want to switch from code to annotations: I want to be able to autowire beans from configs. Now (in code way of context creation) I should write something like appContext.getBean("jdbcTemplate", JdbcTemplate.class) in test methods. It will be great if I will be able to write

@Autowired
private JdbcTemplate jdbcTemplate;

and this will work :)

Anna
  • 189
  • 4
  • 9

1 Answers1

1

Seems you are using two versions of JUnit at the same time: JUnit 4 and JUnit 5. (or use JUnit4 api and JUnit5 api the same time)

Where annotation @Test comes from in your FunctionalTest?

Is it org.junit.Test? Or is it org.junit.jupiter.api.Test?

Seems it is from org.junit.jupiter.api.Test.

Then you should use @ExtendWith(SpringExtension.class instead of @RunWith(SpringJUnit4ClassRunner.class):

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {BaseConfig.class, Utils.ServConfig.class, Utils.MvcConfig.class, MyApplication.class, StorageTestConfig.class}, 
                  loader = AnnotationConfigContextLoader.class)
@ActiveProfiles("functionalTest")
@PropertySource(value = "classpath:test-context.properties")
class FunctionalTest {
      @Autowired
      private ApplicationContext applicationContext;

}

Note that SpringExtension is available since 5.0 version. If you're using lower version, you have to use JUnit4, mark test methods with org.junit.Test

In test class I call it like that: It works fine, no problems.

@RunWith(SpringJUnit4ClassRunner.class) is worthless here. You run this test using JUnit5. @RunWith not considered. But @BeforeEach is considered. Hence it's working.

In your FunctionalTest no annotations considered so it's not working. Use either JUnit4 (@org.junit.Test, @RunWith) or JUnit5 (@org.junit.jupiter.api.Test, @ExtendWith).

Seems you are using two versions of JUnit at the same time: JUnit 4 and JUnit 5.

If you're not migrating from JUnit4 to JUnit 5, consider using only one version of JUnit.

Denis Zavedeev
  • 7,627
  • 4
  • 32
  • 53
  • Thank you, yes, I changed RunWith on ExtendWith and it started to do something :) – Anna Sep 09 '18 at 11:27
  • But now it throws exception that I described in UPDATE part in my question. – Anna Sep 09 '18 at 11:42
  • I think using `ApplicationContext` rather than `AbstractRefreshableWebApplicationContext` in `Utils.ServConfig` would help. – Denis Zavedeev Sep 09 '18 at 11:48
  • It seems to me as design problem. You can hack it injecting `ApplicationContext` and casting it to any subclass of `ApplicationContext` you need where necessary. Please consider asking a new question because the problem we're discussing is going out of scope originally asked question – Denis Zavedeev Sep 09 '18 at 12:05