在测试期间替换具有Autowired依赖性的Spring bean

问题描述 投票:0回答:1

我试图让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依赖项的类不是组件扫描的一部分,也会出错。

有办法避免这种情况吗?

spring inversion-of-control javabeans autowired applicationcontext
1个回答
0
投票

你应该能够用@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);
© www.soinside.com 2019 - 2024. All rights reserved.