Spring测试:在测试中创建几个类
我有一个没有实现类的接口Spring测试:在测试中创建几个类,spring,unit-testing,spring-test,Spring,Unit Testing,Spring Test,我有一个没有实现类的接口 public interface MyInterface { String getName(); } 我还有另一个类,它将MyInterface作为依赖项 @Component public class SomeClass { @Autowired private MyInterface implementation; public MyInterface someMethod(List<MyInterface>
public interface MyInterface {
String getName();
}
我还有另一个类,它将MyInterface
作为依赖项
@Component
public class SomeClass {
@Autowired
private MyInterface implementation;
public MyInterface someMethod(List<MyInterface> list){
//logic
}
}
@组件
公共类{
@自动连线
私有接口实现;
公共MyInterface方法(列表){
//逻辑
}
}
我必须测试
SomeClass
,但我没有MyInterface
实现类。当我可以使用@Autowired
将它们作为springbeans
获取时,是否可以在测试中创建一些MyInterface
实现类,并将它们添加到ApplicationContext
中?假设您使用JUnit 5,可以使用@TestConfiguration
并在那里提供实现:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
class SomeServiceTest {
@Autowired
private MyInterface myInterface;
@TestConfiguration
static class TestConfig {
@Bean
public MyInterface myInterface() {
/**
* Long version of implementing your interface:
*
* return new MyInterface() {
* @Override
* public String getName() {
* return null;
* }
* };
*/
// shorter ;-)
return () -> "Hello World!";
}
}
@Test
void test() {
SomeService someService = new SomeService(myInterface);
System.out.println(someService.doFoo());
}
}
但您也可以使用Mockito,为您的MyInterface
创建一个mock,并进行快速单元测试:
@ExtendWith(MockitoExtension.class)
class SomeServiceTest {
@Mock
private MyInterface myInterface;
@InjectMocks
private SomeService someService;
@Test
void test() {
when(myInterface.getName()).thenReturn("Test");
System.out.println(someService.doFoo());
}
}
虽然上面的代码在技术上符合您的要求,但正如J Asgarov在评论中提到的那样,始终考虑这样做是有意义的。 < P>假设您使用JUnit 5,则可以使用<代码> @ TestStase并提供一个实现:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
class SomeServiceTest {
@Autowired
private MyInterface myInterface;
@TestConfiguration
static class TestConfig {
@Bean
public MyInterface myInterface() {
/**
* Long version of implementing your interface:
*
* return new MyInterface() {
* @Override
* public String getName() {
* return null;
* }
* };
*/
// shorter ;-)
return () -> "Hello World!";
}
}
@Test
void test() {
SomeService someService = new SomeService(myInterface);
System.out.println(someService.doFoo());
}
}
但您也可以使用Mockito,为您的MyInterface
创建一个mock,并进行快速单元测试:
@ExtendWith(MockitoExtension.class)
class SomeServiceTest {
@Mock
private MyInterface myInterface;
@InjectMocks
private SomeService someService;
@Test
void test() {
when(myInterface.getName()).thenReturn("Test");
System.out.println(someService.doFoo());
}
}
虽然上面的代码在技术上符合您的要求,但正如J Asgarov在评论中提到的那样,始终考虑这样做是有意义的。这并不能带来任何东西——接口是抽象的,您永远不会测试一个总是测试实现的接口。在测试中创建一些东西只是为了让测试通过,这有什么意义?除非它是一个功能接口,您可以使用lambdas摆脱它,而lambdas使用getName没有任何意义,它不会带来任何东西-接口是一个抽象,否则您永远不会测试接口—您总是测试实现。在测试中创建一些东西只是为了让测试通过,这有什么意义?除非它是一个功能性接口,您可以使用lambdas,而使用getName则没有意义