我有一个Kiwi spec文件,看起来像这样:
#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
运行规范导致此代码行[[theValue(collection.objects.count) should] equal:theValue(1)];
这是奇怪的部分 - 如果我从规范中移除整个context(@"then removing 1 object", ^{...})
块,则上述测试通过。
这让我相信在失败的测试之前[collection removeObject:object]
行正在执行。我有一种感觉,我可能会误解执行块的顺序。
任何建议都将不胜感激!
答案 0 :(得分:10)
你是正确的,[collection removeObject:object]
在失败的测试之前被执行。将Kiwi测试视为两次通过:
it
/ specify
个语句运行一次,并为每个测试重复正确的设置/拆卸代码请注意,Kiwi测试文件中的大多数代码都被指定为发送到Kiwi函数的一系列块。任何不遵循Kiwi块模式的代码,例如初始化/修改collection
变量的代码,都可能因此在意外时间执行。在这种情况下,所有的集合修改代码都是在设置测试时第一次执行时执行的,然后运行测试。
使用collection
修饰符声明__block
,并使用beforeEach
来实例化和修改collection
对象:
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", ^{
...
beforeEach
块告诉Kiwi每单元测试专门运行给定代码一次,并且对于嵌套上下文,块将根据需要按顺序执行。所以Kiwi会做这样的事情:
// 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)]
__block
修饰符将确保通过所有这些块函数正确保留和修改collection
对象引用。