Spring - 在test

时间:2015-08-05 15:05:52

标签: spring testing service configuration javabeans

在我的spring启动应用程序中,我有一个服务bean(带有@Service注释),我想在特定的JUnit测试中模拟这个服务(不是在所有的测试中)。如何仅针对一个特定测试替换此服务bean?

服务声明为:

@Service
public class LocalizationServiceImpl implements LocalizationService {
   ...
}

App配置类:

@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages="my.package")
@EntityScan

public class Application {
...
}

测试类:

@Transactional
@SpringApplicationConfiguration(classes = LocalizationServiceTest.LocalizationServiceTestConfig.class)
public class LocalizationServiceTest extends ESContextTest {

    @Autowired
    private LocalizationService locService;

    @Configuration  
    public static class LocalizationServiceTestConfig {

        @Bean
        public LocalizationService localizationServiceImpl() {
            return mock(LocalizationService.class);
        }

    }
}

测试班父母:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public abstract class ESContextTest {
...
}

但这不起作用。当我运行测试时,原始的LocalizationServiceImpl用于自动装配的locService属性。这出现在日志文件中:     跳过[BeanMethod:name = localizationService,declaringClass = ... LocalizationServiceTest $ LocalizationServiceTestConfig]的bean定义:bean“localizationService”的定义已经存在。此顶级bean定义被视为覆盖。

当我在LocalizationServiceTestConfig中为@Bean方法使用不同的名称时,例如localizationServiceMock()(与原始实现类名不同)然后spring throws

'No qualifying bean of type is defined: expected single matching bean but found 2: localizationServiceImpl,localizationServiceMock'

所以我认为使用相同的名称是正确的。

只有工作解决方案是从LocalizationServiceImpl类中删除@Service注释并为正常(非测试)应用程序运行创建配置,如

@Configuration 
public class BeansConfig {
    @Bean
    public LocalizationService localizationServiceImpl() {
        return new LocalizationServiceImpl();
    }
}

然后在测试运行中,自动装配正确的模拟实现。

但是应该可以通过@Service注释做同样的事情,不应该吗?

感谢您的建议。

1 个答案:

答案 0 :(得分:9)

我自己找到了一个解决方案:重命名localizationServiceImpl(),例如到班级localizationServiceMock()的{​​{1}},并使用LocalizationServiceTestConfig注释该方法。

但为什么简单地用相同的“id”重新定义bean?不通过xml-config工作吗?