xcode Xcode中私有方法的单元测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1098550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 18:39:41  来源:igfitidea点击:

Unit Testing of private methods in Xcode

objective-ccocoaxcodetddocunit

提问by Abizern

I'm trying out test driven development in a toy project. I can get the tests working for the public interface to my classes (although I'm still on the fence because I'm writing more testing code than there is in the methods being tested).

我正在一个玩具项目中尝试测试驱动开发。我可以让测试工作在我的类的公共接口上(尽管我仍然处于观望状态,因为我编写的测试代码比正在测试的方法中的代码要多)。

I tend to use a lot of private methods becuase I like to keep the public interfaces clean; however, I'd still like to use tests on these methods.

我倾向于使用很多私有方法,因为我喜欢保持公共接口干净;但是,我仍然想对这些方法进行测试。

Since Cocoa is a dynamic language, I can still call these private methods, but i get warnings in my tests that my class may not respond to these methods (although it clearly does). Since I like to compile with no warnings here are my questions:

由于 Cocoa 是一种动态语言,我仍然可以调用这些私有方法,但是我在测试中收到警告说我的类可能不会响应这些方法(尽管它显然会响应)。因为我喜欢在没有警告的情况下编译,所以我的问题是:

  1. How do i turn off these warnings in Xcode?
  2. Is there something else I could do to turn off these warnings?
  3. Am I doing something wrong in trying 'white box' testing?
  1. 如何在 Xcode 中关闭这些警告?
  2. 我还能做些什么来关闭这些警告?
  3. 我在尝试“白盒”测试时做错了什么吗?

回答by Quinn Taylor

Remember that there's actually no such thing as "private methods" in Objective-C, and it's not just because it's a dynamic language. By design, Objective-C has visibility modifiers for ivars, but not for methods — it's not by accident that you can call any method you like.

请记住,Objective-C 中实际上没有“私有方法”这样的东西,这不仅仅是因为它是一种动态语言。按照设计,Objective-C 具有用于 ivars 的可见性修饰符,但没有用于方法——您可以调用任何您喜欢的方法并非偶然。

@Peter's suggestion is a great one. To complement his answer, an alternative I've used (when I don't want/need a header just for private methods) is to declare a category in the unit test file itself. (I use @interface MyClass (Test)as the name.) This is a great way to add methods that would be unnecessary bloat in the release code, such as for accessing ivars that the class under test has access to. (This is obviously less of an issue when properties are used.)

@Peter的建议很棒。为了补充他的回答,我使用的另一种方法(当我不想要/只需要私有方法的标头时)是在单元测试文件本身中声明一个类别。(我使用它@interface MyClass (Test)作为名称。)这是在发布代码中添加不必要膨胀的方法的好方法,例如用于访问被测类有权访问的 ivars。(当使用属性时,这显然不是一个问题。)

I've found this approach makes it easy to expose and verify internal state, as well as adding test-only methods. For example, in this unit test file, I wrote an -isValidmethod for verifying correctness of a binary heap. In production, this method would be a waste of space, since I assume a heap is valid — I only care about it when testing for unit test regressions if I modify the code.

我发现这种方法可以轻松公开和验证内部状态,以及添加仅测试方法。例如,在这个单元测试文件中,我写了一个-isValid验证二进制堆正确性的方法。在生产中,这种方法会浪费空间,因为我假设堆是有效的——如果我修改代码,我只在测试单元测试回归时关心它。

回答by Peter Hosey

How do i turn off these warnings in Xcode?

如何在 Xcode 中关闭这些警告?

Don't.

别。

Is there something else I could do to turn off these warnings?

我还能做些什么来关闭这些警告?

Don't.

别。

Am I doing something wrong in trying 'white box' testing?

我在尝试“白盒”测试时做错了什么吗?

No.

不。

The solution is to move your private methods to a category in its own header. Import this header into both the real class and test-case class implementation files.

解决方案是将您的私有方法移动到其自己的标题中的类别。将此标头导入真实类和测试用例类实现文件。

回答by Andrew Burns

Looks like another question has the answer: Is there a way to suppress warnings in Xcode?

看起来另一个问题有答案:有没有办法在 Xcode 中抑制警告?

回答by Jon Steinmetz

While having a private header or defining your own category are probably more correct solutions there is also another very simple solution: cast the object to (id) before calling the method.

虽然拥有私有标头或定义您自己的类别可能是更正确的解决方案,但还有另一个非常简单的解决方案:在调用方法之前将对象强制转换为 (id)。

回答by user2067021

If you don't want to distribute your private method implementations across multiple source files, a refinement to the Category solution is to define an Extension (essentially an anonymous Category - refer to Apple's documentation) in a header file that's imported by both your existing class' implementation and the relevant unit test source files.

如果您不想跨多个源文件分发私有方法实现,则对 Category 解决方案的改进是在由现有类导入的头文件中定义一个扩展(本质上是一个匿名 Category - 请参阅Apple 的文档) ' 实现和相关的单元测试源文件。

Using an Extension allows the compiler to warn you if the implementation of the private method is not present in the main @implementation block. This linkillustrates it nicely.

如果私有方法的实现不存在于主 @implementation 块中,则使用扩展允许编译器警告您。这个链接很好地说明了它。

回答by Alois Holub

I was dealing with the same issue when I started with TDD few days ago. I've found this very interesting point of view in Test-Driven iOS Developmentbook:

几天前我开始使用 TDD 时,我正在处理同样的问题。我在Test-Driven iOS Development一书中发现了这个非常有趣的观点:

I have often been asked, “Should I test my private methods?” or the related question “How should I test my private methods?” People asking the second question have assumed that the answer to the first is “Yes” and are now looking for a way to expose their classes' private interfaces in their test suites.

My answer relies on observation of a subtle fact: You already have tested your private methods. By following the red–green–refactor approach common in test-driven development, you designed your objects' public APIs to do the work those objects need to do. With that work specified by the tests—and the continued execution of the tests assuring you that you haven't broken anything—you are free to organize the internal plumbing of your classes as you see fit.

Your private methods are already tested because all you're doing is refactoring behavior that you already have tests for. You should never end up in a situation where a private method is untested or incompletely tested, because you create them only when you see an opportunity to clean up the implementation of public methods. This ensures that the private methods exist only to support the class's that they must be invoked during testing because they are definitely being called from public methods.

我经常被问到,“我应该测试我的私有方法吗?” 或者相关的问题“我应该如何测试我的私有方法?” 问第二个问题的人假设第一个问题的答案是“是”,现在正在寻找一种方法来在他们的测试套件中公开他们的类的私有接口。

我的回答依赖于对一个微妙事实的观察:您已经测试了您的私有方法。通过遵循测试驱动开发中常见的红-绿-重构方法,您设计了对象的公共 API 来完成这些对象需要完成的工作。有了测试指定的工作——以及测试的持续执行确保你没有破坏任何东西——你可以自由地组织你认为合适的类的内部管道。

您的私有方法已经过测试,因为您所做的只是重构您已经测试过的行为。您永远不应该遇到私有方法未经测试或未完全测试的情况,因为只有在您看到清理公共方法实现的机会时才创建它们。这确保私有方法的存在仅用于支持在测试期间必须调用它们的类,因为它们肯定是从公共方法调用的。

回答by Henry Sou

Easy Job. Steps: 1. You have -(NSString*)getTestString; in your target m file for interface Foo

轻松的工作。步骤: 1. 你有 -(NSString*)getTestString; 在接口 Foo 的目标 m 文件中

  1. Add a category in your unit test file:

    @interface DemoHomeViewController() -(NSString*)getTestString; @end

  1. 在您的单元测试文件中添加一个类别:

    @interface DemoHomeViewController() -(NSString*)getTestString; @结尾

Then, do anything you want now.

那么,现在就做你想做的任何事情。