如何编写一个单元测试来检查我的属性是否在 iOS 上的 dealloc 中释放?
我对 TDD 和单元测试还很陌生,我正在一个业余项目中尝试一下。
我有点陷入对 dealloc 方法进行单元测试的困境。
我们都知道释放自定义属性并在 dealloc 中将它们设置为 nil 是一个很好的做法:
-(void) dealloc{
[myProperty release];
myProperty = nil;
[super dealloc];
}
我如何编写一个单元测试来检查此行为?
显然,这行不通:
[myObject release]
STAssertNil(myObject.myProperty,@"myProperty should be released and set to nil in dealloc")
有什么建议吗? 谢谢 !
I'm pretty new to TDD and unit testing and I'm giving it a try in a side project.
And I'm kinda stuck in unit testing the dealloc method.
We all know it is a good practice to release custom properties and set them to nil in the dealloc :
-(void) dealloc{
[myProperty release];
myProperty = nil;
[super dealloc];
}
How could I write a unit test that check this behaviour ?
Obviously, this does not work :
[myObject release]
STAssertNil(myObject.myProperty,@"myProperty should be released and set to nil in dealloc")
Any suggestion ?
thanks !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设您可以执行上述操作,您实际上要测试什么?我的想法如下:
测试 -release 会减少保留计数
测试当保留计数达到零时 NSObject 的垃圾收集机制调用 -dealloc
测试当调用 -dealloc 时,myProperty 被释放
这是单元测试的错误粒度,第一点和第二点不是您要测试的事 - 假设它是由苹果进行单元测试的。因此,上面唯一的单元测试是:
现在,这段代码(非常正确)没有任何逻辑,也不会产生任何输出。所以,我认为单元测试实际上是偏执和不必要的(类似于测试编译器是否实际工作)。
但如果我确实想测试它,我会这样做:
显然你通常不应该直接调用 -dealloc,但如果你想对 -dealloc 进行单元测试,这正是你应该做的(或者它不是一个单元) -测试)。鉴于这是非常糟糕的做法,而且测试对你的帮助很小,我认为你不应该打扰。
Assuming you could do the above, what would you actually be testing? Here is what i think:
testing that -release decrements the retainCount
testing that when retainCount reaches zero NSObject's Garbage Collection mechanism calls -dealloc
testing that when -dealloc is called, myProperty is released
This is the wrong granularity for a unit test, points one and two are not your business to test - assume it is unit tested by apple. So, the only bit of the above that is a unit test is:
Now, this piece of code (quite rightly) has no logic whatsoever and produces no output. So, i believe that unit testing it is actually paranoid and unnessesary (akin to testing that the compiler actually works).
But if i did want to test it i would do it like so:
Obviously you should never normally directly call -dealloc, but if you wanted to unit-test -dealloc that is exactly what you should do (or it isn't a unit-test). Given that this is extremely bad practise and the test gains you very little, i don't think you should bother.
这对于 TDD 来说绝对是大材小用。您希望使用 TDD 测试单元功能并使用其他工具捕获更简单的错误。 (我只是担心,如果您开始以这种详细程度编写测试,您将永远无法完成项目。)我个人并不认为引用计数是单元接口的一部分,所以对我来说,它只是超出了单元测试本身的范围。
我建议使用仪器。运行所有测试并对其进行检测(在 OS X 上,我们从 10.5 开始使用“Instruments”应用程序,在 Linux 上我们使用 Valgrind)。检测将告诉您是否所有对象都已释放或者是否存在内存泄漏。我还建议确保您测试错误路径 - 根据我的经验,大多数内存泄漏发生在其他错误同时发生时。
我使用一个自定义测试脚本来运行所有测试,并且它有一个用于检测它们的选项标志。我并不总是对它们进行检测,因为完整的检测水平会大大减慢测试速度。
但是,如果您想以困难的方式做事:
对过时的 Obj-C 1.0 风格表示歉意。
This is definitely overkill for TDD. You want to test unit functionality with TDD and catch simpler errors with another tool. (I'm just worried that if you start writing tests at this level of detail, you will never be able to finish a project.) I don't personally consider refcounts to be part of a unit's interface, so for me, it's just outside the scope of the unit test itself.
I suggest using instrumentation. Run through all your tests and instrument them (on OS X, we use the "Instruments" app since 10.5, on Linux we use Valgrind). The instrumentation will tell you whether all your objects are freed or whether you have a memory leak. I also recommend making sure that you test error paths — in my experience, most memory leaks happen when other errors happen at the same time.
I use a custom testing script which runs through all the tests, and it has an option flag for instrumenting them. I don't always instrument them because the full level of instrumentation slows down the tests quite a bit.
However, if you want to do things the hard way:
Apologies for the archaic, Obj-C 1.0 style.