我试图让Spring将具有autowired依赖关系的类替换为没有这些autowire依赖关系的另一个(测试类),但我总是得到像这样的NoSuchBeanDefinitionException:
引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有'com.experiments.beanreplacement.client.Connection'类型的限定bean可用:预期至少有1个bean可以作为autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
我创建了一个简化示例来显示我的问题。
我的客户端包(Connection.java和TcpClient.java)中有两个类,我的应用程序包中有两个类(MessageSender.java和Scheduler.java)
package com.experiments.beanreplacement.client;
@Component
public class Connection {
public void send(String msg) { System.out.println("Connection send: " + msg); }
...
TcpClient.java自动连接Connection类:
@Component
public class TcpClient {
@Autowired
Connection connection;
public void send(String msg) {
System.out.println("TcpClient send");
connection.send(START_OF_MESSAGE + msg + END_OF_MESSAGE);
}
}
MessageSender类使用TcpClient发送消息:
package com.experiments.beanreplacement.application;
@Component
public class MessageSender {
@Autowired
TcpClient client;
public void sendAMessage() {
client.send("Hello world!");
client.send("Bye bye...");
}
}
我已经设置了一个使用JUnit运行它的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
public class MessageSenderTest {
@Autowired
MessageSender messageSender;
@Test
public void testMessageSender() {
messageSender.sendAMessage();
}
}
TcpClientMock类:
package client;
@Primary
public class TcpClientMock extends com.experiments.beanreplacement.client.TcpClient{
@Override
public void send(String msg) {
System.out.println("Mock client send: " + msg);
}
...
applicationContext.xml中
<bean class="client.TcpClientMock" name="client" >
</bean>
<context:component-scan base-package="com.experiments.beanreplacement.application">
</context:component-scan>
...
在applicationContext.xml文件中,我将MessageSender类中自动装配的TcpClient替换为另一个(TcpClientMock)。
我已经将组件扫描调整为仅查看MessageSender和TcpClientMock的路径,希望避免必须处理原始TcpClient和底层连接的autowire依赖关系。
但是,我仍然得到“没有类型'com.experiments.beanreplacement.client.Connection'的限定bean可用:预计至少有一个bean有资格作为autowire候选者。”即使使用autowire依赖项的类不是组件扫描的一部分,也会出错。
有办法避免这种情况吗?
你应该能够用@MockBean模拟你的TcpClient
bean。在你测试添加:
@MockBean
TcpClient client;
在您的测试方法中,您可以指定send()
方法的行为,如下所示:
String msg = "anything";
doAnswer(i -> {
System.out.println("Mock client send: " + msg);
return null;
}
).when(client).send(msg);