簡體   English   中英

如何在@SpringBootTest 中模擬@PostConstruct 中使用的bean 的行為

[英]How to mock behaviour of a bean used in @PostConstruct in @SpringBootTest

我一直在尋找一段時間,但我找不到解決方案。 我需要模擬另一個 class 的 @PostConstruct 中使用的 class。 我的課是這樣的:

@Component
class A {
    private final B b;
    private String s;

    public A(B b) {this.b = b;}

    @PostConstruct
    public void postConstruct() {
        s = b.get().getString().toUpperCase();
    }
}

@Component
class B {
    private final C c;

    public B(C c) {this.c = c;}

    public C get() {return c;}
}

@Component
class C {
    public C() throws Exception {throw new Exception();}

    String getString() {return "C";}
}

現在我創建了失敗的測試,因為C的構造函數失敗:

@SpringBootTest
class DemoApplicationTests {
    @Autowired A a;

    @Test
    public void canLoadContext() {
        assertThat(a).isNotNull();
    }
}

所以我嘗試模擬C class:

@SpringBootTest
class DemoApplicationTests {
    @MockBean
    static C c;

    @Autowired
    A a;

    @BeforeEach
    public void beforeEach() {
        when(c.getString())
            .thenReturn("C_mocked");
    }

    @Test
    public void canLoadContext() {
        assertThat(a).isNotNull();
    }
}

但是這種方式在s = b.get().getString().toUpperCase();行中出現 NPE 失敗。 因為b中的C object 與我用@MockBean的不同。 getString()被調用時,它返回null並且我們在調用.toUpperCase()時得到一個 NPE。

我也嘗試過像這樣覆蓋模擬:

    @Configuration
    @AutoConfigureBefore
    static class TestContext {
        @Primary
        public C c() {
            return when(mock(C.class).getString())
                .thenReturn("C_mocked").getMock();
        }
    }

但在這種情況下,我收到此錯誤:

沒有可用的“com.example.demo.A”類型的合格 bean:預計至少有 1 個有資格作為自動裝配候選者的 bean。

可以請人幫忙嗎?

我不知道如何將其標記為重復。 但是請看一下這個https://stackoverflow.com/a/58517289/11538031

解決方案仍然是這樣的:

@Component
class A {
    private final B b;
    private String s;

    public A(B b) {this.b = b;}

    @PostConstruct
    public void postConstruct() {
        s = b.get().getString().toUpperCase();
    }
}

@Component
class B {
    private final C c;

    public B(C c) {this.c = c;}

    public C get() {return c;}
}

@Component
class C {
    public C() throws Exception {throw new Exception();}

    String getString() {return "C";}
}
@SpringBootTest
class DemoApplicationTests {

    @Autowired
    A a;

    @Test
    public void canLoadContext() {
        assertThat(a).isNotNull();
    }

    @TestConfiguration
    public static class TestContext {
        @Bean
        @Primary
        public C c() {
            return when(mock(C.class).getString())
                .thenReturn("C_mocked").getMock();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM