我有一个springboot app(v1.3.5)
我的主要申请是:
@SpringBootApplication
@ComponentScan({"com.akrome"})
public class InboxCoreApplication {
public static void main(String[] args) {
SpringApplication.run(InboxCoreApplication.class, args);
}
}
在软件包的某处,我将repo定义为实现:
@Repository
public class CouchbaseServiceImpl implements CouchbaseService {
在其他地方,我有一个使用该界面的课程:
@Repository
public class InboxObjectRepositoryImpl {
@Autowired
private CouchbaseService couchbaseService;
我还有一个测试版的界面:
@Repository
public class CouchbaseServiceTestImpl implements CouchbaseService {
现在。在我的测试中,我想简单地将接口映射重新指向测试实现,同时保持主配置组件扫描定义的所有其他内容。但它一直在吃香蕉。我得到的最接近的是:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {InboxCoreApplication.class, TestConfig.class})
public class InboxServiceTest {
@Autowired
CouchbaseServiceTestImpl couchBaseServiceTestImpl;
TestConfig在哪里:
@Configuration
public class TestConfig {
CouchbaseServiceTestImpl couchbaseServiceTestImpl = new CouchbaseServiceTestImpl();
public CouchbaseService couchbaseService() {
return couchbaseServiceTestImpl;
}
}
但每次它都抱怨重复的bean(bc它看到两个实现),或者它注入2个不同的测试实现实例,一个在测试类中,一个在实际程序中(wat?)。
有什么建议吗?
答案 0 :(得分:1)
我认为你的问题在于下课。为什么要重新实现CouchbaseService接口并将其作为测试版本。这样做的真正意义何在?您应该开发单元测试类来测试主要源的功能。您正在创建该源类的测试版本并创建单元测试以测试该测试版本。这样做有什么意义?
@Repository
public class CouchbaseServiceTestImpl implements CouchbaseService {
所以应该更好的实现,删除CouchbaseServiceTestImpl类。编写单元测试直接测试CouchbaseServiceImpl。 (您也可以删除TestConfig类)
所以代码应该是这样的。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {InboxCoreApplication.class})
public class InboxServiceTest {
@Autowired
CouchbaseServiceImpl couchbaseServiceImpl ;
抱怨重复bean的真正原因可以描述如下。
如果使用@ Repository,@ Component或@Service注释任何类,则Spring IOC容器将自动实例化这些类,然后在加载Spring应用程序上下文时在应用程序上下文中注册。
因此,您有两个CouchbaseService接口的实现。 1. CouchbaseServiceImpl 2. CouchbaseServiceTestImpl
由于这两个类都已使用@Repository注释,因此spring应用程序容器将实例化这两个类,并将在IOC容器中维护这两个对象。这两个实例都可以分配给CouchbaseService接口引用。
查看代码中的以下行。
@Autowired
private CouchbaseService couchbaseService;
现在,spring应用程序容器在可疑的情况下找出相关的匹配bean(是否应该使用CouchbaseServiceImpl或CouchbaseServiceTestImpl。两个bean都有资格进行分配)。因此,它会警告副本,而不会进行分配。
您有两种选择。
删除其中一个类中的@Repository注释。最好在CouchbaseServiceTestImpl中删除它。 (更好地删除那个类,正如我之前解释的那样)
按照您的意愿保留所有课程。 user @Qualifier告诉spring应用程序容器有关赋值的真实匹配bean。
所以代码应该如下更改。
@Repository("couchbaseServiceTestImpl")
public class CouchbaseServiceTestImpl implements CouchbaseService {
@Repository("couchbaseServiceImpl")
public class CouchbaseServiceImpl implements CouchbaseService {
@Repository
public class InboxObjectRepositoryImpl {
@Autowired
@Qualifier("couchbaseServiceTestImpl")
private CouchbaseService couchbaseService;
所以它将为CouchbaseService引用分配一个CouchbaseServiceTestImpl实例。
答案 1 :(得分:1)
我想我找到了它。
应该是用户个人资料:
@Repository
@Profile("application")
public class CouchbaseServiceImpl implements CouchbaseService {
和
@Repository
@Profile("test")
public class CouchbaseServiceTestImpl implements CouchbaseService {
在我的测试中我只是:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {InboxCoreApplication.class})
@ActiveProfiles("test")
public class InboxObjectRepositoryImplTest {