Spring 为什么@MockBean 不能使用配置文件自动装配接口

Spring why @MockBean can't autowire an interface using profile

我有一个包含两个实现的接口。使用哪个实现取决于环境(生产、开发、测试……)。因此,我使用 Spring 个配置文件。我正在使用配置文件来实例化正确的实现。

@Configuration
public class BeanConfiguration {

    @Profile({"develop","test-unit"})
    @Bean(name = "customerEmailSender")
    public CustomerEmailSender emailSenderImpl_1(){
        return new EmailSenderImpl_1();
    }

    @Profile({"prod"})
    @Bean(name = "customerEmailSender")
    public CustomerEmailSender emailSenderImpl_2(){
        return new EmailSenderImpl_2();
    }
}

当 Spring 容器启动时(具有特定配置文件),正确的 bean 会自动连接到 class,并且一切正常。

@Component
public class CustomerEmailProcessor {

    @Autowire
    private CustomerEmailSender customerEmailSender;
    
    ...
}

我还有一个测试 class,我想在其中自动装配 bean。我正在使用 @Mock 进行自动装配。 配置文件在测试 class 中设置为“test-unit”。因此,我希望 spring 容器在配置 class 中查找要实例化的正确 bean。但这不会发生。 相反,抛出异常:
由以下原因引起:java.lang.IllegalStateException:无法注册模拟 bean .... 需要一个匹配的 bean 来替换但找到了 [customerEmailSender,emailSenderImpl_1,emailSenderImpl_2]

使用@Autowire 注解时,一切正常。但是当然,bean 不再被嘲笑了,这就是我需要的。

@RunWith(SpringRunner.class)
@ActiveProfiles(profiles = {"test-unit"})
@Import(BeanConfiguration.class)
public class CustomerEmailResourceTest {

    @MockBean
    private CustomerEmailSender customerEmailSender;
    
}

我在配置 class 中放置了一个断点,我可以看到在测试 class 中使用 @Autowire 时,实例化了正确的 bean(在行“return 新 EmailSenderImpl_1();"。 使用@Mock 时,根本不会实例化任何bean。 Spring 不会在行 "return new EmailSenderImpl_1();"

为什么Spring使用@Mock注解可以找到正确的bean

@Mock 注释必须是 Spring 不使用配置 class“BeanConfiguration.java”的原因。毕竟这是有道理的。