可以在单元测试中重置dispatch_once的状态,以使其再次运行 [英] Possible to reset state of dispatch_once in unit test, to make them run again

查看:405
本文介绍了可以在单元测试中重置dispatch_once的状态,以使其再次运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在单元测试撕裂中重置dispatch_once代码的状态?

Is it possible to reset the state of dispatch_once code in a unit test tearDown?

我认为,如果我们的单元测试可以在一个真正干净的状态下运行会很好,但是我们正在为dispatch_once和通过一次Dispatch创建的单例而苦苦挣扎.

I think it would be nice if our unit tests could run from a really clean state, but we are struggling with dispatch_once and some singletons made with dispatch once.

推荐答案

我首先要指出,在除测试以外的任何情况下,这都不是一件好事.即使这样,也要格外小心-AliSoftware在下面的注释中提供了一些详细信息和示例代码.另请参见有趣的答案,我可以将dispatch_once_t谓词声明为成员变量而不是静态变量吗?,其中包括一些重要信息<从马的嘴里a href ="https://stackoverflow.com/a/19845164/"> .

I should note first that this isn't a good thing to do in any situation other than testing; even then, proceed with care -- AliSoftware provides some details and example code in comments below. See also the interesting answers at Can I declare a dispatch_once_t predicate as a member variable instead of static?, including some important information from the horse's mouth.

dispatch_once_ttypedef d long.它的假值为0.如果将该标志重置为0,dispatch_once()将再次运行.您的问题是只是"如何从另一个编译单元更改静态变量的值.为此,我认为您需要一个调试/单元测试挂钩,如下所示:

dispatch_once_t is a typedefd long. Its false value is 0. If you reset that flag to 0, dispatch_once() will run again. Your problem is "just" how to change the value of a static variable from another compilation unit. For this, I think you need a debug/unit test hook, like so:

MakeWhoopie.h

MakeWhoopie.h

#import <Foundation/Foundation.h>

void makeWhoopie(void);

#ifdef DEBUG
void resetDispatchOnce(void);
#endif

MakeWhoopie.m

MakeWhoopie.m

#include "MakeWhoopie.h"

static dispatch_once_t * once_token_debug;

void makeWhoopie(void)
{

    static dispatch_once_t once_token;
    once_token_debug = &once_token;    // Store address of once_token
                                       // to access it in debug function.
    dispatch_once(&once_token, ^{
        NSLog(@"That's what you get, folks.");
    });

    NSLog(@"Making whoopie.");
}

#ifdef DEBUG
void resetDispatchOnce(void)
{
    *once_token_debug = 0;
}
#endif

(您也可以将once_token移至文件级别并直接进行更改.)

(You could also move once_token up to file level and change it directly.)

尝试一下:

#import <Foundation/Foundation.h>
#import "MakeWhoopie.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        makeWhoopie();
        makeWhoopie();
        resetDispatchOnce();
        makeWhoopie();
    }
    return 0;
}

结果:

2012-06-07 18:45:28.134 ResetDispatchOnce [8628:403]伙计,这就是你得到的.
2012-06-07 18:45:28.163 ResetDispatchOnce [8628:403]制作whoopie.
2012-06-07 18:45:28.164 ResetDispatchOnce [8628:403]制作whoopie.
2012-06-07 18:45:28.165 ResetDispatchOnce [8628:403]伙计,这就是您得到的.
2012-06-07 18:45:28.165 ResetDispatchOnce [8628:403]制作whoopie.

2012-06-07 18:45:28.134 ResetDispatchOnce[8628:403] That's what you get, folks.
2012-06-07 18:45:28.163 ResetDispatchOnce[8628:403] Making whoopie.
2012-06-07 18:45:28.164 ResetDispatchOnce[8628:403] Making whoopie.
2012-06-07 18:45:28.165 ResetDispatchOnce[8628:403] That's what you get, folks.
2012-06-07 18:45:28.165 ResetDispatchOnce[8628:403] Making whoopie.

这篇关于可以在单元测试中重置dispatch_once的状态,以使其再次运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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