在 Manus 中运行任何 Skill
一键导入
一键导入
一键在 Manus 中运行任何 Skill
开始使用testing
星标1
分支0
更新时间2026年1月29日 12:49
테스트 작성 전략, JUnit 5, Reactive Streams TCK
安装
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
SKILL.md
readonly菜单
테스트 작성 전략, JUnit 5, Reactive Streams TCK
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Backpressure 개념, 전략, 구현 가이드
코드 품질 가이드, 클린 코드 원칙, 리팩토링 패턴
Reactive Streams 디버깅 전략, 로깅, 에러 추적
Reactive Operator 구현 패턴, 체이닝, 변환
Reactive Streams 전체 규약 (39개 규칙) 상세 설명
| name | testing |
| description | 테스트 작성 전략, JUnit 5, Reactive Streams TCK |
/\
/ \ TCK Tests (규약 준수 검증)
/----\
/ \ Integration Tests (Operator 체이닝)
/--------\
/ \ Unit Tests (개별 Publisher/Subscriber)
/------------\
class ArrayPublisherTest {
@Test
@DisplayName("request(n)만큼만 onNext 호출")
void shouldEmitRequestedElements() {
// Given
ArrayPublisher<Integer> publisher = new ArrayPublisher<>(1, 2, 3, 4, 5);
TestSubscriber<Integer> subscriber = new TestSubscriber<>();
// When
publisher.subscribe(subscriber);
subscriber.request(3);
// Then
assertThat(subscriber.getReceivedItems()).containsExactly(1, 2, 3);
assertThat(subscriber.isCompleted()).isFalse();
}
@Test
@DisplayName("모든 요소 소비 후 onComplete 호출")
void shouldCompleteAfterAllElements() {
// Given
ArrayPublisher<Integer> publisher = new ArrayPublisher<>(1, 2);
TestSubscriber<Integer> subscriber = new TestSubscriber<>();
// When
publisher.subscribe(subscriber);
subscriber.request(Long.MAX_VALUE);
// Then
assertThat(subscriber.getReceivedItems()).containsExactly(1, 2);
assertThat(subscriber.isCompleted()).isTrue();
}
}
public class TestSubscriber<T> implements Subscriber<T> {
private Subscription subscription;
private final List<T> receivedItems = new ArrayList<>();
private Throwable error;
private boolean completed = false;
@Override
public void onSubscribe(Subscription s) {
this.subscription = s;
}
@Override
public void onNext(T item) {
receivedItems.add(item);
}
@Override
public void onError(Throwable t) {
this.error = t;
}
@Override
public void onComplete() {
this.completed = true;
}
// Helper methods
public void request(long n) {
subscription.request(n);
}
public void cancel() {
subscription.cancel();
}
public List<T> getReceivedItems() {
return Collections.unmodifiableList(receivedItems);
}
public boolean isCompleted() {
return completed;
}
public Throwable getError() {
return error;
}
}
TCK(Technology Compatibility Kit)는 Reactive Streams 규약 준수를 자동으로 검증합니다.
public class ArrayPublisherTckTest extends PublisherVerification<Integer> {
public ArrayPublisherTckTest() {
super(new TestEnvironment());
}
@Override
public Publisher<Integer> createPublisher(long elements) {
Integer[] array = new Integer[(int) elements];
for (int i = 0; i < elements; i++) {
array[i] = i;
}
return new ArrayPublisher<>(array);
}
@Override
public Publisher<Integer> createFailedPublisher() {
return new ErrorPublisher<>(new RuntimeException("Test error"));
}
}
required_createPublisher1MustProduceAStreamOfExactly1Elementrequired_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElementsrequired_spec102_maySignalLessThanRequestedAndTerminateSubscriptionrequired_spec109_mustIssueOnSubscribeForNonNullSubscriberpublic class StepVerifier<T> {
private final Publisher<T> publisher;
private final List<Consumer<T>> expectations = new ArrayList<>();
public static <T> StepVerifier<T> create(Publisher<T> publisher) {
return new StepVerifier<>(publisher);
}
public StepVerifier<T> expectNext(T expected) {
expectations.add(actual ->
assertThat(actual).isEqualTo(expected)
);
return this;
}
public StepVerifier<T> expectNextCount(long count) {
// count개의 요소 기대
return this;
}
public void verifyComplete() {
// 구독하고 검증 실행
}
public void verifyError(Class<? extends Throwable> errorClass) {
// 에러 검증
}
}
// 사용 예
StepVerifier.create(publisher)
.expectNext(1)
.expectNext(2)
.expectNext(3)
.verifyComplete();
@Test
void shouldHandleConcurrentRequests() throws InterruptedException {
ArrayPublisher<Integer> publisher = new ArrayPublisher<>(/* 1000 elements */);
TestSubscriber<Integer> subscriber = new TestSubscriber<>();
publisher.subscribe(subscriber);
ExecutorService executor = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
executor.submit(() -> {
subscriber.request(10);
latch.countDown();
});
}
latch.await(5, TimeUnit.SECONDS);
// 총 1000개 요청, 1000개 요소
assertThat(subscriber.getReceivedItems()).hasSize(1000);
}
reactive-spec: 규약 상세debugging: 테스트 실패 분석