SpyBean 没有被注入到任何地方

我很难将 spy bean 放入我的 ApplicationContext。我有一颗豆称为公用事业类型的工具:


@Component("utilities")

public class Utilities {


<snip>


    /**

     * Returns a random int. This is provided mostly for testing mock-ability

     *

     * @return a random integer

     */

    public int getRandom() {

        return (int) (Math.random() * Integer.MAX_VALUE);

    }

}

它是在我的 Spring 集成流程间接引用的类中使用的。


然后我有这个木星测试:


@TestInstance(Lifecycle.PER_CLASS)

@FixMethodOrder(MethodSorters.NAME_ASCENDING)

@ExtendWith(SpringExtension.class)

@ContextConfiguration( classes = {

    XmlLocations.class,

    VisitorManager.class,

    Utilities.class,

    UnixTimeChannel.class

})

@WebMvcTest

//@TestExecutionListeners( { MockitoTestExecutionListener.class })

public class FullIntegrationTest {


    @Autowired

    private MockMvc mvc;


    @SpyBean

    private Utilities utilities;


    private ClientAndServer mockServer;


    private static final int MOCK_SERVER_PORT = 9089;


    @BeforeAll

    public void setUpBeforeClass() {


        Mockito.when(utilities.getRandom()).thenReturn(Integer.MAX_VALUE);


        mockServer = ClientAndServer.startClientAndServer(MOCK_SERVER_PORT);

        RestAssuredMockMvc.mockMvc(mvc);

        (new MockServerPingInit()).initializeExpectations(mockServer);

        (new MockServerFullIntegrationInit()).initializeExpectations(mockServer);

    }


    @Test

    public void t00200_IncomingMessage() {


        RestAssuredMockMvc.given()

            .queryParam("example", "example")

            .when()

            .request("POST", "/api/v1/incoming")

            .then()

            .statusCode(equalTo(200));

    }


<snip>

但是即使我创建了 spy bean 并在它上面使用了 when/thenReturn,它也不会漂浮到我的应用程序上下文中等待被调用并返回它的模拟随机值。


我知道utilities.getRandom() 方法被调用,因为我可以在它上面放置一个断点并调试测试,并且它命中了getRandom 方法,但是当我尝试添加一个如上所示的间谍bean 并模拟getRandom 时返回一个固定值来测试断点仍然命中,所以我可以告诉真正的方法不是正在调用模拟。


我试过将 when/thenReturn 也放在测试中,以防为时过早,但这无济于事。


显然我做错了什么,可能在概念上是错误的。呸!


不负相思意
浏览 418回答 2
2回答

四季花海

好的,谢谢大家的帮助。无意沮丧,发布配置和流程对我的想法没有帮助,因为我在下面发现了:仔细检查有一个例外:org.springframework.expression.AccessException: Could not resolve bean reference against BeanFactory有问题的参考是对我使用 @SpyBean 的实用程序中的一个方法:&nbsp; &nbsp; <int:transformer&nbsp; &nbsp; &nbsp; &nbsp; expression="@utilities.asMap('licence_id', headers[licenceId], 'message', 'Delivered: ' + headers[confirmedMessage], 'secured_session_id', headers[visitorSession].getSecureSessionId())" />它不是一个单独的 ApplicationContext 而是 SpEL 不会接受间谍 bean,因为引用已更改或类似。所以,我不理会这些实用程序,而是改造了它内部的另一个 bean 来生成数字,并在其上使用了 SpyBean。现在 Spring Integration/SpEL 再次感到高兴,因为它使用的实用程序 bean 是正确的,并且模拟发生在该 bean 内部并且对 SpEL 透明。@Componentpublic class RandomSupplier implements Supplier<Double> {&nbsp; &nbsp; @Override&nbsp; &nbsp; public Double get() {&nbsp; &nbsp; &nbsp; &nbsp; return Math.random();&nbsp; &nbsp; }}public class FullIntegrationTest {&nbsp; &nbsp; @Autowired&nbsp; &nbsp; private MockMvc mvc;&nbsp; &nbsp; @SpyBean&nbsp; &nbsp; private RandomSupplier randomSupplier;&nbsp; &nbsp; @Autowired // This is only necessary for the toy test below&nbsp; &nbsp; private Utilities utilities;&nbsp; &nbsp; @BeforeEach&nbsp; &nbsp; public void setupAfterInit() {&nbsp; &nbsp; &nbsp; &nbsp; Mockito.when(randomSupplier.get()).thenReturn(0.5);&nbsp; &nbsp; }&nbsp; &nbsp; @Test&nbsp; &nbsp; public void t0() throws IOException {&nbsp; &nbsp; &nbsp; System.out.println(utilities.getRandom());&nbsp; &nbsp; }...现在 Spring Integration/SpEL 再次感到高兴,因为它工作的实用程序 bean 是正确的,并且模拟发生在该 bean 内部。三个教训:不要窥探 Spring Integration Flow 中 SpEL 中直接引用的 bean;阅读日志;你永远不可能有足够的间接性:)

慕尼黑的夜晚无繁华

我试图用最少的配置重现你的问题:@ExtendWith(SpringExtension.class)@ContextConfiguration(classes = {Ctx.class})public class XTest {&nbsp; @SpyBean&nbsp; private Random random1;&nbsp; @Autowired private Supplier<Integer> intSupplier;&nbsp; @Test&nbsp; public void test() {&nbsp; &nbsp; Mockito.when(random1.nextInt()).thenReturn(Integer.MAX_VALUE);&nbsp; &nbsp; int i = intSupplier.get();&nbsp; &nbsp; System.out.println("i=" + i);&nbsp; }&nbsp; @Configuration&nbsp; public static class Ctx {&nbsp; &nbsp; @Bean&nbsp; &nbsp; static Random random1() {&nbsp; &nbsp; &nbsp; return ThreadLocalRandom.current();&nbsp; &nbsp; }&nbsp; &nbsp; @Bean&nbsp; &nbsp; static Supplier<Integer> intSupplier(Random random1) {&nbsp; &nbsp; &nbsp; return random1::nextInt;&nbsp; &nbsp; }&nbsp; }}正如预期的那样打印i=2147483647所以,你的运行时配置一定有问题......你能分享一下吗?我猜 spring-integration 正在使用另一个 ApplicationContext。我知道这不是答案,如果没有帮助,我会删除它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java