繁体   English   中英

在测试过程中更换具有自动装配依赖性的Spring bean

[英]Replacing a Spring bean that have Autowired dependency during testing

我试图让Spring用另一个不具有这些自动装配依赖关系的(测试类)替换具有自动装配依赖关系的类,但是我总是以这样的NoSuchBeanDefinitionException结尾:

由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为'com.experiments.beanreplacement.client.Connection'的合格bean:期望至少有1个有资格作为自动装配候选的bean。 依赖项注释:{@ 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和基础Connection的自动装配依赖项。

但是,我仍然获得“没有可用的'com.experiments.beanreplacement.client.Connection类型的合格bean:期望至少有1个有资格作为自动装配候选者的bean”。 即使使用自动装配依赖项的类也不在组件扫描中,也会发生错误。

有办法避免这种情况吗?

您应该能够使用@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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM