Kiwi iOS上下文块的奇怪排序 [英] Strange ordering of Kiwi iOS context blocks

查看:88
本文介绍了Kiwi iOS上下文块的奇怪排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Kiwi规格文件,看起来像这样:

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

运行该规范会导致代码[[theValue(collection.objects.count) should] equal:theValue(1)];

Running the spec results in one failure at this line of code [[theValue(collection.objects.count) should] equal:theValue(1)];

这是奇怪的部分-如果我从规格中删除了整个context(@"then removing 1 object", ^{...})块,则上述测试通过了.

Here's the strange part - if I remove the whole context(@"then removing 1 object", ^{...}) block from the spec the aforementioned test passes.

这使我相信[collection removeObject:object]行在测试失败之前就已经执行了.我觉得我可能会误解执行块的顺序.

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.

任何建议将不胜感激!

推荐答案

您正确的认为,在失败的测试之前,正在执行[collection removeObject:object].认为Kiwi测试可以通过两个过程进行操作:

You are correct that [collection removeObject:object] is getting executed before the failing test. Think of Kiwi tests as operating in two passes:

  1. 设置:从头到尾执行测试文件中的代码以设置测试上下文和期望
  2. 执行:运行每个单元测试,基本上每个it/specify语句一个,并为每个测试重复正确的设置/拆卸代码
  1. Setup: the code in your test file is executed from top to bottom to set up the test contexts and expectations
  2. Execution: each unit test is run, basically one per it/specify statement, with the correct setup/teardown code repeated for each test

请注意,Kiwi测试文件中的大多数代码都指定为发送给Kiwi函数的一系列块.因此,任何不遵循Kiwi块模式的代码(例如,初始化/修改collection变量的代码)都可能在意外的时间执行.在这种情况下,设置测试时,所有集合修改代码都将在第一遍过程中执行,然后然后运行测试.

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 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.

使用__block修饰符声明collection,并使用beforeEach实例化和修改collection对象:

Declare collection with a __block modifier, and use beforeEach to instantiate and modify the collection object:

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每个单元测试一次专门运行给定的代码,并且在嵌套上下文中,这些块将根据需要顺序执行.所以猕猴桃会做这样的事情:

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:

// 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对象引用.

The __block modifier will ensure that the collection object reference can be properly retained and modified through all of these block functions.

这篇关于Kiwi iOS上下文块的奇怪排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆