【问题标题】:How to configure @MockBean before @PostConstruct?如何在@PostConstruct 之前配置@MockBean?
【发布时间】:2021-06-06 05:42:06
【问题描述】:

我有一个服务,它有一个我想模拟的 DataProvider

问题:服务使用@PostConstruct 中的数据提供者。但是当我使用@MockBean 时,@PostConstruct 中不存在模拟值。

我能做什么?

@Service
public class MyService {
    private List<Object> data;

    @Autowired
    private DataProvider dataProvider;
    
    @PostConstruct
    public void initData() {
        data = dataProvider.getData();
    }
    
    public void run() {
        System.out.println(data); //always null in tests
    }
}


@SpringBootTest
public class Test {
    @MockBean
    private DataProvider dataProvider;

    @Test
    public void test() {
        when(dataProvider.getData()).thenReturn(mockedObjects);
        //dataProvider.init(); //this fixes it, but feels wrong
        service.run();
    }
}

【问题讨论】:

  • 您不能在应用程序上下文设置后调用您的测试。您真的需要为此进行集成测试吗?为什么不写一个合适的单元测试呢。
  • 好吧,因为它是(更大的)集成测试的一部分。这部分当然会引起问题......

标签: java spring spring-boot spring-boot-test


【解决方案1】:

恕我直言,单元测试MyService 将是这种特殊情况的更好解决方案(在这种情况下手动调用initService 我不会觉得错),但如果你坚持...

您可以简单地覆盖此特定测试的 DataProvider bean 定义并预先模拟它,例如:

@SpringBootTest(classes = {MyApplication.class, Test.TestContext.class})
public class Test {

    @Test
    public void test() {
        service.run();
    }

    @Configuration
    static class TestContext {

        @Primary
        public DataProvider dataProvider() {
            var result = Mockito.mock(DataProvider.class);
            when(result.getData()).thenReturn(mockedObjects);
            return result;
        }
    }
}

您可能需要将 spring.main.allow-bean-definition-overriding 设置为 true 才能使上述操作生效。

【讨论】:

    猜你喜欢
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 2023-03-26
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    相关资源
    最近更新 更多