I have a Kiwi spec file that looks something like this:
#import "Kiwi.h"
#import "MyCollection.h"
SPEC_BEGIN(CollectionSpec)
describe(@"Collection starting with no objects", ^{
MyCollection *collection = [MyCollection new];
context(@"then adding 1 object", ^{
MyObject *object = [MyObject new];
[collection addObject:object];
it(@"has 1 object", ^{
[collection shouldNotBeNil];
[collection.objects shouldNotBeNil];
[[theValue(collection.objects.count) should] equal:theValue(1)]; //failing test
});
context(@"then removing 1 object", ^{
[collection removeObject:object];
it(@"has 0 objects", ^{
[[theValue(collection.objects.count) should] equal:theValue(0)]; //passing test
});
});
});
});
SPEC_END
Running the spec results in one failure at this line of code [[theValue(collection.objects.count) should] equal:theValue(1)];
Here's the strange part - if I remove the whole context(@"then removing 1 object", ^{...})
block from the spec the aforementioned test passes.
This leads me to believe that the [collection removeObject:object]
line is getting executed before the failing test. I have a feeling I may be misunderstanding the order that blocks are executed in.
Any suggestions would be appreciated!
You are correct that
[collection removeObject:object]
is getting executed before the failing test. Think of Kiwi tests as operating in two passes:it
/specify
statement, with the correct setup/teardown code repeated for each testNote that most of the code in a Kiwi test file is specified as a series of blocks sent to the Kiwi functions. Any code that doesn't follow the Kiwi block patterns, such as your code that initializes/modifies the
collection
variable, might thus execute at an unexpected time. In this case, all of the collection modification code is being executed during the first pass when setting up your tests, and then your tests are run.Solution
Declare
collection
with a__block
modifier, and usebeforeEach
to instantiate and modify thecollection
object:The
beforeEach
blocks tell Kiwi to specifically run the given code once per unit test, and with nested contexts, the blocks will be executed in sequence as needed. So Kiwi will do something like this:The
__block
modifier will ensure that thecollection
object reference can be properly retained and modified through all of these block functions.