Java 测试中的Spring启动覆盖接口
我有一个springboot应用程序(v1.3.5) 我的主要应用是:Java 测试中的Spring启动覆盖接口,java,testing,spring-boot,Java,Testing,Spring Boot,我有一个springboot应用程序(v1.3.5) 我的主要应用是: @SpringBootApplication @ComponentScan({"com.akrome"}) public class InboxCoreApplication { public static void main(String[] args) { SpringApplication.run(InboxCoreApplication.class, args); } } 在包中的某
@SpringBootApplication
@ComponentScan({"com.akrome"})
public class InboxCoreApplication {
public static void main(String[] args) {
SpringApplication.run(InboxCoreApplication.class, args);
}
}
在包中的某个地方,我将回购定义为一个实现:
@Repository
public class CouchbaseServiceImpl implements CouchbaseService {
在其他地方,我有一个使用该接口的类:
@Repository
public class InboxObjectRepositoryImpl {
@Autowired
private CouchbaseService couchbaseService;
@Repository
public class CouchbaseServiceTestImpl 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它看到了两个实现),要么注入了测试实现的两个不同实例,一个在测试类中,一个在实际程序中(wat?)
有什么建议吗?我想你的问题在于下面的课程。为什么要重新实现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("couchbaseServiceTestImpl")
public class CouchbaseServiceTestImpl implements CouchbaseService {
如果您用@Repository、@Component或@Service注释了任何类,那么spring IOC容器将自动实例化这些类,并在加载spring应用程序上下文时在应用程序上下文中注册
因此,您有两个CouchbaseService接口的实现。
1.CouchbaseServiceImpl
2.CouchbaseServiceTestImpl
由于这两个类都使用@Repository进行了注释,因此spring应用程序容器将实例化这两个类,并在IOC容器中维护这两个对象。这两个实例都可以分配给CouchbaseService接口引用
请看代码中的以下行
@Autowired
private CouchbaseService couchbaseService;
现在,spring应用程序容器在查找相关匹配bean(是否应该使用CouchbaseServiceImpl或CouchbaseServiceTestImpl。这两个bean都符合分配条件)方面遇到了问题。因此,它会发出重复警告,不会执行分配
你有两个选择
选项01。
删除其中一个类中的@Repository注释。最好在CouchbaseServiceTestImpl中移除它。(如我前面所述,最好删除该类)
选项02
让所有的课程都按照你的要求进行。user@Qualifier告诉spring应用程序容器分配的真正匹配bean
因此,代码应按如下所示进行更改
@Repository("couchbaseServiceTestImpl")
public class CouchbaseServiceTestImpl implements CouchbaseService {
所以它将把CouchbaseServiceTestImpl的一个实例分配给CouchBaseServiceReference。我想我找到了它 它应该是用户配置文件:
@Repository
@Profile("application")
public class CouchbaseServiceImpl implements CouchbaseService {
及
在我的测试中,我只是:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {InboxCoreApplication.class})
@ActiveProfiles("test")
public class InboxObjectRepositoryImplTest {
您可以在这里添加堆栈跟踪吗?很有意义,您有
CouchbaseServiceTestImpl
和CouchbaseServiceImpl`这两个都是由Spring容器为您的测试加载的。一个是由于TestConfig
而加载的,另一个是由于您导入了InboxCoreApplication
,该应用程序会自动对每个子包进行组件扫描。原因是,这不是我正在测试的。这是一个DB连接对象,当我测试应用程序的其余部分时,我不想连接到DB,只需要使用内存中的模拟。但是我看到了你的观点,但这对我没有帮助,因为注入bean的其他类将无法使用它,因为它们用于非测试命名版本:/