我的项目中有一些Repository
- bean。我将此回购的集合连接到我的一些服务,并迭代地从每个服务中获取数据。但是在我的单元测试中,我想从Spring上下文中排除所有这些存储库(实际实现),并且只使用伪造的。我如何实现它?
答案 0 :(得分:0)
让我们创建一个非常简单的示例来测试我们的自动配置。我们将使用Spring Data创建一个名为MyUser的实体类和一个MyUserRepository接口:
@Entity
public class MyUser {
@Id
private String email;
// standard constructor, getters, setters
}
public interface MyUserRepository
extends JpaRepository<MyUser, String> { }
要启用自动配置,我们可以使用其中一个@SpringBootApplication
或@EnableAutoConfiguration
注释:
@SpringBootApplication
public class AutoconfigurationApplication {
public static void main(String[] args) {
SpringApplication.run(AutoconfigurationApplication.class, args);
}
}
接下来,让我们编写一个保存MyUser实体的JUnit测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(
classes = AutoconfigurationApplication.class)
@EnableJpaRepositories(
basePackages = { "com.baeldung.autoconfiguration.example" })
public class AutoconfigurationTest {
@Autowired
private MyUserRepository userRepository;
@Test
public void whenSaveUser_thenOk() {
MyUser user = new MyUser("user@email.com");
userRepository.save(user);
}
}
由于我们尚未定义DataSource配置,因此应用程序将使用我们创建的自动配置连接到名为myDb
的MySQL数据库。
连接字符串包含createDatabaseIfNotExist=true
属性,因此数据库不需要存在。但是,需要创建用户mysqluser或通过mysql.user属性指定的用户mysqluser,如果它存在,则需要创建。
我们可以检查应用程序日志以查看是否正在使用MySQL数据源:
web - 2017-04-12 00:01:33,956 [main] INFO o.s.j.d.DriverManagerDataSource - Loaded JDBC driver: com.mysql.cj.jdbc.Driver
如果我们想要排除自动配置,我们可以将@EnableAutoConfiguration
注释添加exclude
或excludeName
属性到配置类:
@Configuration
@EnableAutoConfiguration(
exclude={MySQLAutoconfiguration.class})
public class AutoconfigurationApplication {
//...
}
禁用特定自动配置的另一个选项是设置spring.autoconfigure.exclude
属性:
spring.autoconfigure.exclude=com.baeldung.autoconfiguration.MySQLAutoconfiguration
资源链接:Create a Custom Auto-Configuration with Spring Boot
Matt C也在本教程中提供了解决方案:How to exclude *AutoConfiguration classes in Spring Boot JUnit tests?。
答案 1 :(得分:0)
Spring单元测试中很少使用Spring上下文。第一个问题你应该问自己:“我想测试哪些工作单元?”。得到答案后,您应该在隔离中对其进行测试。你不需要弹簧上下文。通常在集成测试中需要Spring上下文。单元测试不得依赖于上下文。
您可以使用@Mock
提供的@InjectMocks
和Mockito
注释。例如:
public class SomeServiceTest {
@InjectMocks
SomeService someService;
@Mock
PersonRepository personRepository;
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}
@Test
public void testFindPersonExpectOk(){
String name = "John";
String secondName = "Doe";
// Configure the behavior for mocked repository
Person person = new Person(name, secondName);
when(personRepository.findByNameAndSecondName(name,
secondName).thenReturn(person);
// Call some method in testing service
Person fetchedPerson = someService.findUser(name, secondName);
// Check that everything is fine
assertThat(fetchedPerson.getName, is(name));
}
}
答案 2 :(得分:0)
以下是解决方案:
@SpringBootApplication
@ComponentScan(basePackages = "my.base.package",
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "my.base.package.repositories.*.*"))
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Bean
public Repository someFakeRepository() {
return new FakeRepository();
}
}
然后是测试班:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class ApplicationTests {
@Autowired
private Repository fakeRepository;
// tests
}
所以我用测试版替换了所有真正的bean。