Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 在单元测试中重写自动连线Bean_Spring_Spring Boot_Spring Annotations - Fatal编程技术网

Spring 在单元测试中重写自动连线Bean

Spring 在单元测试中重写自动连线Bean,spring,spring-boot,spring-annotations,Spring,Spring Boot,Spring Annotations,有没有一种简单的方法可以轻松地在特定的单元测试中重写自动连线bean?编译类中每种类型只有一个bean,因此在这种情况下,自动连接没有问题。测试类将包含额外的模拟。当运行单元测试时,我只想指定一个额外的配置,即基本上,当运行这个单元测试时,使用这个模拟而不是标准bean 对于我所需要的配置文件来说,似乎有点过火了,我不确定使用主注释是否可以实现这一点,因为不同的单元测试可能会有不同的模拟。您应该使用spring配置文件,以便知道在不同的上下文中要使用哪种bean 如果您只是想在测试中提供一个不同

有没有一种简单的方法可以轻松地在特定的单元测试中重写自动连线bean?编译类中每种类型只有一个bean,因此在这种情况下,自动连接没有问题。测试类将包含额外的模拟。当运行单元测试时,我只想指定一个额外的配置,即基本上,当运行这个单元测试时,使用这个模拟而不是标准bean


对于我所需要的配置文件来说,似乎有点过火了,我不确定使用主注释是否可以实现这一点,因为不同的单元测试可能会有不同的模拟。

您应该使用spring配置文件,以便知道在不同的上下文中要使用哪种bean


如果您只是想在测试中提供一个不同的bean,我认为您不需要使用spring概要文件或mockito

只需执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { TestConfig.class })
public class MyTest
{
    @Configuration
    @Import(Application.class) // the actual configuration
    public static class TestConfig
    {
        @Bean
        public IMyService myService()
        {
            return new MockedMyService();
        }
    }

    @Test
    public void test()
    {
        ....
    }
}

注意:使用spring boot 1.3.2/spring 4.2.4进行测试在spring boot 1.4中有一种简单的方法:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MyApplication.class })
public class MyTests {
    @MockBean
    private MyBeanClass myTestBean;

    @Before
    public void setup() {
         ...
         when(myTestBean.doSomething()).thenReturn(someResult);
    }

    @Test
    public void test() {
         // MyBeanClass bean is replaced with myTestBean in the ApplicationContext here
    }
}

我也有类似的问题,我用混合解决了,我发现这一个更有用和可重用。我为测试创建了一个spring概要文件,并创建了一个config类,它以一种非常简单的方式覆盖了我想要模拟的bean:

@Profile("test")
@Configuration
@Import(ApplicationConfiguration.class)
public class ConfigurationTests {

    @MockBean
    private Producer kafkaProducer;

    @MockBean
    private SlackNotifier slackNotifier;

}
通过这样做,我可以@Autowire这些模拟bean,并使用mockito对它们进行验证。主要优点是,现在所有测试都无缝地获得模拟bean,而无需对每个测试进行任何更改。 通过以下方式进行测试:

弹簧靴1.4.2


正如mats.nowak所评论的那样,
@ContextConfiguration
对此很有用

假设父测试类类似于:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/some-dao-stuff.xml"
    ,"classpath:spring/some-rest-stuff.xml"
    ,"classpath:spring/some-common-stuff.xml"
    ,"classpath:spring/some-aop-stuff.xml"
    ,"classpath:spring/some-logging-stuff.xml"
    ,"classpath:spring/some-services-etc.xml"
})
public class MyCompaniesBigTestSpringConfig {
...
创建子测试类:

package x.y.z;
@ContextConfiguration
public class MyOneOffTest extends MyCompaniesBigTestSpringConfig {
...
并放入src/test/resources/x/y/z/MyOneOffTest-context.xml中

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <bean id="widgetsService" class="com.mycompany.mydept.myservice.WidgetsService" primary="true" />

</beans>

widgetsService
bean将覆盖(代替)主配置xml(或Java配置)中定义的bean。了解 还要注意默认的-context.xml文件。举个例子。
更新:我必须添加
primary=“true”
,显然这是必需的。

您尝试过@ContexConfiguration吗?您希望在同一测试类中为不同的测试类使用不同的模拟,还是为不同的测试方法使用不同的模拟?是的,这是我设想的,在测试配置中设置标准配置以及要覆盖的bean的测试配置。对整个类使用不同的mock就足够了。我得到了“bean的定义…已经存在。这个顶级bean定义被认为是一个重写。”我必须将“myService()”方法更改为其他名称,例如“myservicecomck()”。我还建议使用@Primary annotation(对于IMyService)来确保TestConfig配置中定义的bean将覆盖应用程序配置中的bean。@Kacper86因为您使用的是Spring 4.1或更低版本,所以该错误在4.2中得到了修复,
@Import
注释用于什么?只有当您想在测试配置中使用现有bean时,才需要这样做吗?@Kacper86:添加“Primary”注释解决了Spring关于为接口找到2个实现的抱怨。非常感谢。我还必须使用
@Primary
注释覆盖原始bean(SpringBootStarter父级:2.0.0.RELEASE,SpringBootStarter测试:2.0.4.RELEASE);thx@kacper86什么是
MyApplication
?您应该用包含main()函数并用@springbootapplixation注释的邮件应用程序类的名称替换它。如果您想用Mockito mock替换bean,这是最好的答案。否则(例如,如果你想注入一个自定义对象)就没有帮助了。要使
@MockBean
工作,你需要
@TestExecutionListeners(MockitoTestExecutionListener.class)
。其他一些注释或配置可以神奇地为您做到这一点。检查文档)