我很难将间谍bean放入我的ApplicationContext。我有一个名为 utilities 的bean,类型为 Utilities:
@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 Integration流间接引用的类中使用的。
然后我有这个木星测试:
@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>
但是,即使我创建了间谍bean并在其上使用了when/thenReturn,它也不会浮动到我的应用程序上下文中,等待被调用并返回其模拟的随机值。
我知道方法utilities.getRandom()会被调用,因为我可以在它上面放置一个断点并调试测试,它会命中getRandom方法,但是当我尝试添加如上所示的间谍bean并模拟getRandom以返回一个固定值用于测试时,断点仍然会命中,因此我可以告诉真实的方法,而不是mock被调用。
我也试过把when/thenReturn放在测试中,以防太早,但没有帮助。
很明显我做错了,可能是概念上的错误。哈普!
2条答案
按热度按时间14ifxucb1#
我试图用最小的配置重现你的问题:
正如预期的那样,
所以,你的运行时配置一定有问题...你能分享一下吗我猜spring-integration正在使用另一个ApplicationContext。我知道这不是答案,如果没有帮助,我会删除它。
dy1byipe2#
好的,谢谢你们的帮助。我不想让人沮丧,我认为发布配置和流程不会有帮助,因为我发现了下面的内容:
仔细观察有一个例外:
有问题的引用是我使用@SpyBean的实用程序中的一个方法:
它不是一个单独的ApplicationContext,而是SpEL不会接受间谍bean,因为引用已经更改或类似。
因此,我不去管这些实用程序,而是在其内部改造了另一个bean来生成数字,并在其上使用SpyBean。现在Spring Integration/SpEL又高兴了,因为它使用的实用程序bean是正确的,并且mocking发生在bean内部,对SpEL透明。
现在Spring Integration/SpEL又高兴了,因为它正在工作的实用程序bean是正确的,并且mocking发生在该bean内部。
三个教训:不要在Spring集成流中窥探SpEL中直接引用的bean;阅读日志;你永远不会有足够的间接:)