我试图通过以下方式对我的用例进行单元测试:
@RunWith(MockitoJUnitRunner.class)
public class DeviceCheckInUseCaseTest extends InstrumentationTestCase {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
ShopRepository shopRepository;
@Mock
UserRepository userRepository;
@Mock
SettingRepository settingRepository;
private DeviceCheckInUseCase deviceCheckInUseCase;
private PublishSubject<CheckInResult> checkinSubject;
private static final String SHOPID = "shop id";
private static final String MEMBERID = "member id";
private TestSubscriber<CheckInResult> testSubscriber;
@Mock
Activity activity;
@Before
public void setUp() {
testSubscriber = new TestSubscriber<>();
checkinSubject = PublishSubject.create();
when(shopRepository
.checkIn(
activity,
SHOPID,
MEMBERID,
-60
)
).thenReturn(checkinSubject.asObservable());
when(settingRepository.getCheckinRssiThreshold()).thenReturn(-60);
deviceCheckInUseCase = new DeviceCheckInUseCase(userRepository, shopRepository, settingRepository);
}
@Test
public void testCheckInSucceeded() {
final ArrayList<CheckInResult> succeeded = new ArrayList<CheckInResult>();
final ArrayList<Throwable> failed = new ArrayList<Throwable>();
this.deviceCheckInUseCase.checkIn(activity, SHOPID, MEMBERID)
.doOnNext(new Action1<CheckInResult>() {
@Override
public void call(CheckInResult checkInResult) {
succeeded.add(checkInResult);
}
})
.doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
failed.add(throwable);
}
})
.subscribe(testSubscriber)
;
testSubscriber.assertValueCount(0);
assertEquals(0, succeeded.size());
assertEquals(0, failed.size());
checkinSubject.onNext(new CheckInSuccess());
this.testSubscriber.assertValueCount(1);
assertEquals(1, succeeded.size());
assertEquals(0, failed.size());
}
}
以下是我的DeviceCheckInUseCase.java
public class DeviceCheckInUseCase {
private UserRepository userRepository;
private ShopRepository shopRepository;
private SettingRepository settingRepository;
// private Subscription
@Inject
public DeviceCheckInUseCase(UserRepository userRepository, ShopRepository shopRepository, SettingRepository settingRepository) {
this.userRepository = userRepository;
this.shopRepository = shopRepository;
this.settingRepository = settingRepository;
}
public Observable<CheckInResult> checkIn(final Activity context, final String shopId, final String memberId) {
return Observable.create(new Observable.OnSubscribe<CheckInResult>() {
@Override
public void call(final Subscriber<? super CheckInResult> subscriber) {
final Subscription subscription = new BooleanSubscription();
shopRepository
.checkIn(context, shopId, memberId, settingRepository.getCheckinRssiThreshold())
.retryWhen(new Func1<Observable<? extends Throwable>, Observable<Integer>>() {
@Override
public Observable<Integer> call(Observable<? extends Throwable> failure) {
return failure.flatMap(new Func1<Throwable, Observable<Integer>>() {
@Override
public Observable<Integer> call(Throwable result) {
if (result instanceof BluetoothFailure) {
return Observable.error(result);
} else if (!subscription.isUnsubscribed()) {
return Observable.just(0);
} else {
return Observable.error(result);
}
}
});
}
})
.flatMap(new Func1<CheckInResult, Observable<CheckInResult>>() {
@Override
public Observable<CheckInResult> call(final CheckInResult checkInResult) {
return userRepository.checkin()
.map(new Func1<Void, CheckInResult>() {
@Override
public CheckInResult call(Void aVoid) {
return checkInResult;
}
});
}
})
.subscribe(subscriber);
}
});
}
public boolean enableCheckin() {
return userRepository.enableCheckin();
}
}
正如您所看到的,我希望succeeded
数组增加一个元素,但其大小仍为空。
我一直在试图弄清楚为什么会发生这种情况,遇到了testchedulers和testsubscribers的异步测试,但我不认为我正在使用它:
在@Before
我正在补充:
subscriber = new TestSubscriber<>();
checkinSubject.subscribe(subscriber);
并将@Test
部分中的断言更改为:
this.subscriber.assertValueCount(0);
assertEquals(0, succeeded.size());
assertEquals(0, failed.size());
this.checkinSubject.onNext(new CheckInSuccess());
this.subscriber.assertValueCount(1);
assertEquals(1, succeeded.size());
assertEquals(0, failed.size());
assertValueCount
工作正常但succeeded
仍保持不变。我如何获得成功的断言?
答案 0 :(得分:1)
您的订阅链已损坏。你应该订购下游而不是upperstream。因此,请doOnError
之后订阅,而不是Subject
上的订阅dircetly。
this.deviceCheckInUseCase.checkIn()
.doOnNext(succeeded::add)
.doOnError(failed::add)
.subscribe(subscriber);
以下是完整的测试代码:
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import rx.Observable;
import rx.Subscription;
import rx.observers.TestSubscriber;
import rx.subjects.PublishSubject;
import rx.subscriptions.BooleanSubscription;
public class Q47049714 {
public static class BluetoothFailure extends Exception {
}
public static class CheckInSuccess implements CheckInResult {
}
public static interface CheckInResult {
}
public class ShopRepository {
public Observable<CheckInResult> checkIn() {
return checkinSubject;
}
}
public class UserRepository {
public Observable<Void> checkIn() {
return Observable.just(null);
}
}
public class DeviceCheckInUseCase {
ShopRepository shopRepository = new ShopRepository();
UserRepository userRepository = new UserRepository();
public Observable<CheckInResult> checkIn() {
return Observable.create(subscriber -> {
Subscription subscription = new BooleanSubscription();
shopRepository
.checkIn()
.retryWhen(failure -> failure.flatMap(result -> {
if (result instanceof BluetoothFailure) {
return Observable.error(result);
} else if (!subscription.isUnsubscribed()) {
return Observable.just(0);
} else {
return Observable.error(result);
}
}))
.flatMap(checkInResult -> userRepository.checkIn().map(v -> checkInResult))
.subscribe(subscriber);
});
}
}
PublishSubject<CheckInResult> checkinSubject;
DeviceCheckInUseCase deviceCheckInUseCase;
TestSubscriber<CheckInResult> subscriber;
@Before
public void setUp() {
checkinSubject = PublishSubject.create();
subscriber = new TestSubscriber<>();
deviceCheckInUseCase = new DeviceCheckInUseCase();
}
@Test
public void testCheckInSucceeded() {
final ArrayList<CheckInResult> succeeded = new ArrayList<>();
final ArrayList<Throwable> failed = new ArrayList<>();
deviceCheckInUseCase.checkIn()
.doOnNext(succeeded::add)
.doOnError(failed::add)
.subscribe(subscriber);
subscriber.assertValueCount(0);
assertEquals(0, succeeded.size());
assertEquals(0, failed.size());
checkinSubject.onNext(new CheckInSuccess());
subscriber.assertValueCount(1);
assertEquals(1, succeeded.size());
assertEquals(0, failed.size());
}
}
答案 1 :(得分:-1)
也许你可以尝试添加
doOnNext
在{{1}}之前。但我不确定它是否会有所帮助。