Database Reference
In-Depth Information
Testing
performBlock()
executions can be tricky since you need some way to signal
to “the outside world” from inside the block about the test status. Luckily, there are
new features in
XCTestCase
called
expectations
that help with this.
The example below shows how you might use an expectation to wait for an
asynchronous method to complete before finishing the test:
let
expectation =
self
.
expectationWithDescription
(
"Done!"
);
someService.callMethodWithCompletionHandler() {
expectation.fulfill()
}
self
.
waitForExpectationsWithTimeout
(
2.0
, handler:
nil
)
The key is that something must fulfill or trigger the expectation so the test moves
forward. The wait method at the end takes a time parameter (in seconds), so that
the test isn't waiting forever and can time out (and fail) in case the expectation is
never fulfilled.
In the example provided, you can see
fulfill()
is called explicitly in the
completion handler passed in to the tested method. With Core Data saves, it's
easier to listen for the
NSManagedObjectDidSaveNotification
, since it happens in a
place where you can't call
fulfill()
explicitly.
Add a new method to
CamperServiceTests.swift
to test that the root context is
getting saved when a new camper is added:
func
testRootContextIsSavedAfterAddingCamper() {
//1
let
expectRoot =
self
.
expectationForNotification
(
NSManagedObjectContextDidSaveNotification
,
object:
coreDataStack
.
rootContext
) {
notification
in
return
true
}
//2
let
camper =
camperService
.
addCamper
(
"Bacon Lover"
,
phoneNumber:
"910-543-9000"
)
//3
self
.
waitForExpectationsWithTimeout
(
2.0
) {
error
in
XCTAssertNil
(error,
"Save did not occur"
)
}
}