This may not answer your question exactly, but it may give you an idea of ββhow to effectively test your signals. So far I have used 2 approaches:
XCTestCase and TRVSMonitor
TRVSMonitor is a small utility that pauses the current thread for you while you execute your statements. For instance:
TRVSMonitor *monitor = [TRVSMonitor monitor]; [[[self.service searchPodcastsWithTerm:@"security now"] collect] subscribeNext:^(NSArray *results) { XCTAssertTrue([results count] > 0, @"Results count should be > 0"; [monitor signal]; } error:^(NSError *error) { XCTFail(@"%@", error); [monitor signal]; }]; [monitor wait];
As you can see, I suggest that the monitor wait immediately after I subscribe and signal it, to stop waiting at the end of subscribeNext and error blocks to continue its execution (so that other tests can also run). This approach has the advantage of not relying on a static timeout , so your code can work as long as it needs to.
Using CocoaPods, you can easily add TRVSMonitor to your project:
pod "TRVSMonitor", "~> 0.0.3"
Specta and Expecta strong>
Specta is a BDD / TDD (behavior / test driven) test environment. Expecta is a framework that provides more convenient matches for approval. It has built-in support for asynchronous tests. This allows you to write more descriptive tests using ReactiveCocoa, for example:
it(@"should return a valid image, with cache state 'new'", ^AsyncBlock { [[cache imageForURL:[NSURL URLWithString:SECURITY_NOW_ARTWORK_URL]] subscribeNext:^(UIImage *image) { expect(image).notTo.beNil(); expect(image.cacheState).to.equal(JPImageCacheStateNew); } error:^(NSError *error) { XCTFail(@"%@", error); } completed:^{ done(); }]; });
Note the use of ^ AsyncBlock { . Using just ^ { would imply a synchronous test.
Here you call the done () function to signal the completion of the asynchronous test. I believe Specta uses an internal timeout of 10 seconds.
Using CocoaPods, you can easily add Expecta and Specta:
pod "Expecta", "~> 0.2.3" pod "Specta", "~> 0.2.1"