反应性 Spring Mono 和 doOnNext
Reactive Spring Mono and doOnNext
我在我的项目中使用 spring-boot-starter-webflux、reactor-test 和 spring-boot-starter-test 2.0.0.M7。在我的 RepositoryInMemory.class
中有一个 List<String>
,您可以在其中通过 saveName(Mono<String> name)
方法添加字符串值。您还可以通过 getAllNames()
方法询问所有添加到列表中的值。问题是如何测试RepositoryInMemory.class
?我有 RepositoryInMemoryTest.class
但似乎它不起作用,因为 List<String>
returns 总是 0。我知道问题是 RepositoryInMemory.class
中的 doOnNext
方法,但我不知道不知道为什么以及如何解决它。有谁知道我应该如何创建有效的 Junit 测试用例?
RepositoryInMemory class
package com.example
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Repository
public class RepositoryInMemory {
private final List<String> names = new ArrayList<>();
public Flux<String> getAllNames() {
return Flux.fromIterable(names);
}
public Mono<Void> saveName(Mono<String> name) {
return name.doOnNext(report -> names.add(report)).then();
}
}
RepositoryInMemoryTest class
package com.example
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import reactor.core.publisher.Mono;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RepositoryInMemoryTest {
@Autowired
private RepositoryInMemory repository;
@Test
public void addDataToList_ShouldReturnOne() {
Mono<String> name = Mono.just("Example Name");
repository.saveName(name);
int count = Math.toIntExact(repository.getAllNames().count().block());
assertEquals(1, count);
}
}
我会回答我自己的问题,因为我找到了解决方案。您唯一需要做的就是将这一行 repository.saveName(name);
更改为这一行 repository.saveName(name).block();
。这是激活 doOnNext
方法。
为以后的读者说明,请使用 subscribe()
而不是 block()
。因为block()
实际上会阻塞线程直到接收到下一个信号,这是违反异步概念的。
如果您真的想切换回同步流程,请使用 block()
。
我在我的项目中使用 spring-boot-starter-webflux、reactor-test 和 spring-boot-starter-test 2.0.0.M7。在我的 RepositoryInMemory.class
中有一个 List<String>
,您可以在其中通过 saveName(Mono<String> name)
方法添加字符串值。您还可以通过 getAllNames()
方法询问所有添加到列表中的值。问题是如何测试RepositoryInMemory.class
?我有 RepositoryInMemoryTest.class
但似乎它不起作用,因为 List<String>
returns 总是 0。我知道问题是 RepositoryInMemory.class
中的 doOnNext
方法,但我不知道不知道为什么以及如何解决它。有谁知道我应该如何创建有效的 Junit 测试用例?
RepositoryInMemory class
package com.example
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Repository
public class RepositoryInMemory {
private final List<String> names = new ArrayList<>();
public Flux<String> getAllNames() {
return Flux.fromIterable(names);
}
public Mono<Void> saveName(Mono<String> name) {
return name.doOnNext(report -> names.add(report)).then();
}
}
RepositoryInMemoryTest class
package com.example
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import reactor.core.publisher.Mono;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RepositoryInMemoryTest {
@Autowired
private RepositoryInMemory repository;
@Test
public void addDataToList_ShouldReturnOne() {
Mono<String> name = Mono.just("Example Name");
repository.saveName(name);
int count = Math.toIntExact(repository.getAllNames().count().block());
assertEquals(1, count);
}
}
我会回答我自己的问题,因为我找到了解决方案。您唯一需要做的就是将这一行 repository.saveName(name);
更改为这一行 repository.saveName(name).block();
。这是激活 doOnNext
方法。
为以后的读者说明,请使用 subscribe()
而不是 block()
。因为block()
实际上会阻塞线程直到接收到下一个信号,这是违反异步概念的。
如果您真的想切换回同步流程,请使用 block()
。