可以在单元测试中重置dispatch_once的状态,以使其再次运行 [英] Possible to reset state of dispatch_once in unit test, to make them run again
问题描述
是否可以在单元测试撕裂中重置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_t
是typedef
d long
.它的假值为0.如果将该标志重置为0,dispatch_once()
将再次运行.您的问题是只是"如何从另一个编译单元更改静态变量的值.为此,我认为您需要一个调试/单元测试挂钩,如下所示:
dispatch_once_t
is a typedef
d 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屋!