通过基准中的注释加载应用程序上下文

问题描述 投票:3回答:3

让我们假设我想写一个benchmark为类可以是autowired因此我需要加载application context

我的测试有注释@org.openjdk.jmh.annotations.State(Scope.Benchmark)和主要方法

public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(MyBenchmark.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }

当然,我有一些像这样的基准:

@Benchmark
public void countAllObjects() {
    Assert.assertEquals(OBJECT_COUNT, myAutowiredService.count());
}

现在,问题是我如何注射myAutowiredService

可能解决方案

@Setup方法中手动加载上下文。

ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/application-context.xml");
context.getAutowireCapableBeanFactory().autowireBean(this);

但我不喜欢这个解决方案。我希望我的测试只有注释

@ContextConfiguration(locations = { "classpath:META-INF/application-context.xml" })

然后我就像注射我的豆子一样

@Autowired
private MyAutowiredService myAutowiredService;

但这不起作用。我认为,原因是我没有注释,我的测试应该用Spring运行:

@RunWith(SpringJUnit4ClassRunner.class)

但是没有必要这样做,因为我也没有任何@Test注释方法,因此我将得到No runnable methods异常。

在这种情况下,我可以通过注释来实现加载上下文吗?

java spring unit-testing spring-mvc annotations
3个回答
1
投票

我找到了spring-cloud-sleuth的代码,它对我有用

@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
public class DemoApplicationTests {

    volatile DemoApplication app;

    volatile ConfigurableApplicationContext context;

    private VideoService videoService;

    @Test
    public void contextLoads() throws RunnerException {
        Options opt = new OptionsBuilder()
            .include(DemoApplicationTests.class.getSimpleName())
            .forks(1)
            .build();
        new Runner(opt).run();
    }

    @Setup
    public void setup() {
        this.context = new SpringApplication(DemoApplication.class).run();
        Object o = this.context.getBean(VideoService.class);
        videoService = (VideoService)o;
    }

    @TearDown
    public void tearDown(){
        this.context.close();
    }

    @Benchmark
    public String benchmark(){
        return videoService.find("z");
    }

0
投票

我会选择你已经勾勒出的getAutowireCapableBeanFactory().autowire()解决方案。

必须有一些样板代码加载应用程序上下文并触发自动装配。如果您希望使用注释指定应用程序配置,则安装方法可能如下所示:

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MyBenchmarkWithConfig.class);
context.refresh();

0
投票
@State(Scope.Benchmark)
public static class SpringState {

    AnnotationConfigApplicationContext config;

    @Setup
    public void setup() {
        context = new AnnotationConfigApplicationContext();
        context.register(CLASSNAME.class);
        context.register(ANOTHER_CLASSNAME_TO_BE_LOADED.class);
        context.refresh();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.