我正在尝试对一个简单的流程进行单元测试,它检查文件是否存在,然后执行一些其他任务。
集成流程
@Bean
public IntegrationFlow initiateAlarmAck() {
return IntegrationFlows.from("processAckAlarmInputChannel")
.handle((payload, headers) -> {
LOG.info("Received initiate ack alarm request at " + payload);
File watermarkFile = getWatermarkFile();
if(watermarkFile.isFile()){
LOG.info("Watermark File exists");
return true;
}else{
LOG.info("File does not exists");
return false;
}
})
.<Boolean, String>route(p -> fileRouterFlow(p))
.get();
}
File getWatermarkFile(){
return new File(eventWatermarkFile);
}
@Router
public String fileRouterFlow(boolean fileExits){
if(fileExits)
return "fileFoundChannel";
else
return "fileNotFoundChannel";
}
Run Code Online (Sandbox Code Playgroud)
还有另一个集成流,它从中挑选消息fileNotFoundChannel并进行额外的处理。我不想对这部分进行单元测试。如何停止我的测试以不再做进一步的测试并在发布消息后停止fileNotFoundChannel?
@Bean
public IntegrationFlow fileNotFoundFlow() {
return IntegrationFlows.from("fileNotFoundChannel")
.handle((payload, headers) -> …Run Code Online (Sandbox Code Playgroud) 我的集成测试在启动时遇到了性能问题。
我正在尝试模拟系统的消息传递。为此,我基本上@MockBean在我的网关上使用并使用@EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}). 例子:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApplication.class)
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@ActiveProfiles("test")
@EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class})
public class MyTestIT {
Run Code Online (Sandbox Code Playgroud)
这两个配置很好地完成了这项工作,我的测试运行没有问题,并且与某些外部 RabbitMQ 没有任何依赖关系。
但是spring boot的启动时间非常非常慢。这是大约两分钟只有在这部分配置SimpleMessageListenerContainer,AmqpInboundChannelAdapter,EventDrivenConsumer,RabbitExchangeQueueProvisioner,等。
日志有一些关于问题所在的提示(我剪了很多消息,这是一个示例):
2018-02-09 14:26:37.784 INFO [ms-project-name-service,,,] 13804 --- [ main] o.s.integration.channel.DirectChannel : Channel 'ms-project-name-service:test:-1.channel2-output' has 1 subscriber(s).
2018-02-09 14:26:54.110 INFO [ms-project-name-service,,,] 13804 --- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: channel1-input.anonymous.417FtxKTTce7-_IR0tGuNA, bound to: channel1-input
2018-02-09 14:27:00.147 INFO [ms-project-name-service,,,] 13804 --- [ main] …Run Code Online (Sandbox Code Playgroud) spring integration-testing rabbitmq spring-boot spring-boot-test
我有一个简单的应用程序,其中有几个用 kotlin beans dsl 声明的 bean:
@SpringBootApplication
class App
val beans = beans {
bean<A>()
}
fun main(args: Array<String>) {
runApplication<MatchmakerApp>(*args) {
addInitializers(beans)
}
}
@RestController
class AppController(val a: A) {
// some code
}
class A
Run Code Online (Sandbox Code Playgroud)
我有一个集成测试:
@RunWith(SpringRunner::class)
@SpringBootTest
class AppControllerTest {
@Test
fun dummyTest() {
assert(true)
}
}
Run Code Online (Sandbox Code Playgroud)
启动这个测试我得到
UnsatisfiedDependencyException: Error creating bean with name appController
Caused by: NoSuchBeanDefinitionException: No qualifying bean of type 'A' available:`
Run Code Online (Sandbox Code Playgroud)
似乎在SpringBootTest创建上下文期间未调用 bean 初始值设定项。
我们需要在 SpringBootTest 中添加 kotlin bean dsl 初始值设定项吗? …
控制器.java
@RestController
public class Controller {
@Autowired
private UserService userService;
@Autowired
private BookService bookService;
//Below userService implementation
@PostMapping(value = "/addNewUser", consumes = "application/json")
public void addNewUser(@RequestBody User newUser) {
userService.addNewUser(newUser);
}
@GetMapping(value = "/findUserById/{id}", produces = "application/json")
public User findUserById(@PathVariable("id") Long id) {
return userService.findUserById(id);
}
@GetMapping(value = "/findUserByName/{name}", produces = "application/json")
public User findUserByName(@PathVariable("name") String name) {
return userService.findUserByName(name);
}
Run Code Online (Sandbox Code Playgroud)
UserServiceImpl.java
@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public void addNewUser(User newUser) { …Run Code Online (Sandbox Code Playgroud) 我想为@RestClientTest下面的组件编写一个简单的测试(注意:我可以在不使用@RestClientTest和模拟工作正常的依赖 bean 的情况下完成它。)。
@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationSender {
private final ApplicationSettings settings;
private final RestTemplate restTemplate;
public ResponseEntity<String> sendNotification(UserNotification userNotification)
throws URISyntaxException {
// Some modifications to request message as required
return restTemplate.exchange(new RequestEntity<>(userNotification, HttpMethod.POST, new URI(settings.getNotificationUrl())), String.class);
}
}
Run Code Online (Sandbox Code Playgroud)
和测试;
@RunWith(SpringRunner.class)
@RestClientTest(NotificationSender.class)
@ActiveProfiles("local-test")
public class NotificationSenderTest {
@MockBean
private ApplicationSettings settings;
@Autowired
private MockRestServiceServer server;
@Autowired
private NotificationSender messageSender;
@Test
public void testSendNotification() throws Exception {
String url = "/test/notification";
UserNotification …Run Code Online (Sandbox Code Playgroud) 我正在尝试对来自控制器的调用执行单元测试,但收到NullPointerException。回调返回一个ResponseEntity <Page>对象,如下所示:
@GetMapping
public ResponseEntity<Page<CentroDeCusto>> centrosDeCustos(Pageable paginacao) {
Page<CentroDeCusto> centrosDeCustos = centroDeCustoRepository.departamentosPorDataDeAtualizacao(paginacao);
if (centrosDeCustos.hasContent())
return new ResponseEntity<>(centrosDeCustos, HttpStatus.OK);
else
return new ResponseEntity<>(centrosDeCustos, HttpStatus.NOT_FOUND);
}
Run Code Online (Sandbox Code Playgroud)
这是我的控制器测试类:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CentroDeCustoRestControllerTeste {
@Autowired
private MockMvc mvc;
@MockBean
private CentroDeCustoRepository repository;
@Test
@WithMockUser(username = "teste-app-@teste.com", authorities = {"ADMIN"})
public void aoBuscarCentrosDeCustoRetornarUmaListaComVariosCentrosDeCusto() throws Exception {
PageRequest paginacao = PageRequest.of(1, 10);
List<CentroDeCusto> centrosDeCustos = Arrays.asList(new CentroDeCusto(), new CentroDeCusto());
Page<CentroDeCusto> centrosDeCustosPage = new PageImpl<>(centrosDeCustos, paginacao, centrosDeCustos.size());
given(repository.departamentosPorDataDeAtualizacao(paginacao)).willReturn(centrosDeCustosPage);
mvc.perform(get("/centrosdecustos").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
} …Run Code Online (Sandbox Code Playgroud) 我已经更改了 Spring Boot (2.1.4) 服务,该服务消耗 aRestTemplate以使用@Qualifier. 现在我的测试(使用@RestClientTest和@AutoConfigureWebClient)失败了,因为它无法解析 bean。
我该如何解决?
配置:
@Bean
@Qualifier("eureka")
@LoadBalanced
RestTemplate eurekaRestTemplate() {
Run Code Online (Sandbox Code Playgroud)
服务:
public ClarkClient(
@Qualifier("eureka") RestTemplate restTemplate, ClarkConfiguration configuration)
throws URISyntaxException {
Run Code Online (Sandbox Code Playgroud)
考试:
@ExtendWith({SpringExtension.class, MockitoExtension.class})
@RestClientTest({CastorClient.class, CastorConfiguration.class})
@AutoConfigureWebClient(registerRestTemplate = true)
class CastorClientWebTest {
@Autowired
private CastorClient cut;
@Autowired
private MockRestServiceServer server;
Run Code Online (Sandbox Code Playgroud)
错误:
[2019-04-16T14:02:22,614] [WARN ] [ ....AnnotationConfigApplicationContext] [refresh 557] : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'castorClient' defined …Run Code Online (Sandbox Code Playgroud) I want to test my Spring Boot application's layers - service, data, controllers.
我知道,通过Spring Boot,我们可以在服务器参与或不参与的情况下(通过创建模拟环境)对它们进行测试。所以我的问题是-测试这些层的最佳实践是什么?还是取决于我们要测试的特定层?
java integration-testing springmockito spring-boot spring-boot-test
我想启动 kafka 测试容器并获取它的引导服务器:
@SpringBootTest
@ContextConfiguration(classes = {TestConfig.class, MyApplication.class}, initializers = MyIntegrationTest.Initializer.class)
@Testcontainers
public class MyIntegrationTest {
@Container
private static final KafkaContainer KAFKA = new KafkaContainer();
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(@NotNull ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues values = TestPropertyValues.of(
"spring.kafka.consumer.bootstrap-servers=" + KAFKA.getBootstrapServers(),
"spring.producer.bootstrap-servers=" + KAFKA.getBootstrapServers()
);
values.applyTo(configurableApplicationContext);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是我得到:
java.lang.IllegalStateException: You should start Kafka container first
at org.testcontainers.containers.KafkaContainer.getBootstrapServers(KafkaContainer.java:65) ~[kafka-1.12.2.jar:na]
Run Code Online (Sandbox Code Playgroud) 我是 Spring Boot 的新手。我正在尝试使用 Spring Tool Suite 和 Mysql Workbench 创建一个应用程序,该应用程序使用 JPA、MysqlConnectorJ 作为依赖项。
我有一个名为“CredentialType”的实体
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "mactyp")
public class CredentialType {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="credential_type_id")
private Long id;
@Column(name="credential_type_name")
private String name;
@Column(name="date_added")
private LocalDateTime dateAdded;
@Column(name="date_modified")
private Date dateLastModified;
@Column(name="is_active")
private boolean isActive;
...getters() and setters()...
}
Run Code Online (Sandbox Code Playgroud)
下面的表定义(由 Mysql Workbench 生成的脚本)
CREATE TABLE `mactyp` (
`credential_type_id` int(11) NOT NULL AUTO_INCREMENT,
`credential_type_name` varchar(45) NOT NULL,
`date_added` …Run Code Online (Sandbox Code Playgroud) mysql mysql-workbench spring-data-jpa spring-boot spring-boot-test
spring-boot-test ×10
spring-boot ×8
java ×4
spring ×2
apache-kafka ×1
junit5 ×1
kotlin ×1
mockito ×1
mysql ×1
qualifiers ×1
rabbitmq ×1
spring-mvc ×1
spring-rest ×1
springrunner ×1
unit-testing ×1