Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You are correct that <code>[collection removeObject:object]</code> is getting executed before the failing test. Think of Kiwi tests as operating in two passes:</p> <ol> <li>Setup: the code in your test file is executed from top to bottom to set up the test contexts and expectations</li> <li>Execution: each unit test is run, basically one per <code>it</code>/<code>specify</code> statement, with the correct setup/teardown code repeated for each test</li> </ol> <p>Note 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 <code>collection</code> 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 <em>then</em> your tests are run.</p> <h3>Solution</h3> <p>Declare <code>collection</code> with a <code>__block</code> modifier, and use <code>beforeEach</code> to instantiate and modify the <code>collection</code> object:</p> <pre><code>describe(@"Collection starting with no objects", ^{ __block MyCollection *collection; beforeEach(^{ collection = [MyCollection new]; }); context(@"then adding 1 object", ^{ beforeEach(^{ MyObject *object = [MyObject new]; [collection addObject:object]; }); it(@"has 1 object", ^{ ... }); context(@"then removing 1 object", ^{ beforeEach(^{ [collection removeObject:object]; }); it(@"has 0 objects", ^{ ... </code></pre> <p>The <code>beforeEach</code> 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:</p> <pre><code>// run beforeEach "Collection starting with no objects" collection = [MyCollection new] // run beforeEach "then adding 1 object" MyObject *object = [MyObject new] [collection addObject:object] // execute test "has 1 object" [collection shouldNotBeNil] [collection.objects shouldNotBeNil] [[theValue(collection.objects.count) should] equal:theValue(1)] // run beforeEach "Collection starting with no objects" collection = [MyCollection new] // run beforeEach "then adding 1 object" MyObject *object = [MyObject new] [collection addObject:object] // run beforeEach "then removing 1 object" [collection removeObject:object] // execute test "has 0 objects" [[theValue(collection.objects.count) should] equal:theValue(0)] </code></pre> <p>The <code>__block</code> modifier will ensure that the <code>collection</code> object reference can be properly retained and modified through all of these block functions.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload