如何在iOS单元测试中公开私有属性?

时间:2015-05-08 17:27:15

标签: ios unit-testing

我正在尝试测试一个使用某些类的类的方法。私人财产。我查看了有关如何在单元测试中访问它们的最佳实践,并决定在我的测试实现文件中为该类添加一个类别。它仍然不允许我访问它们,我得到"未经认可的选择器发送到实例"错误。

我的实现类属性定义(在ImplementationClass.m文件的顶部):

//interface to expose private variables of test case class
@interface ImplementationClass (Test)
    @property(readwrite,assign) TWPLoadUnitEnum loadUnit;
    @property(readwrite,assign) BOOL recosMatchTargets;
@end

我的测试类顶部的类别:

        ImplementationClass *realRecosModal = [[ImplementationClass alloc] 
initWithNibName:@"ImplementationClassVC" bundle:nil];
        [realRecosModal setLoadUnit:TWPLoadUnitKg]

我访问属性的地方:

{{1}}

我在调用" setLoadUnit"的行上收到错误。我没有正确公开私有财产吗?

2 个答案:

答案 0 :(得分:1)

@interface ImplementationClass () {
    TWPLoadUnitEnum loadUnit;
    BOOL recosMatchTargets;
}

不是属性,它们是iVars。如果您希望它们成为属性,则需要

@interface ImplementationClass ()
@property (nonatomic) TWPLoadUnitEnum loadUnit;
@property (nonatomic) BOOL recosMatchTargets;

如果你想保留iVar,那么在你的单元测试中

@interface ImplementationClass () {
@public
    TWPLoadUnitEnum loadUnit;
    BOOL recosMatchTargets;
}
@end
  • 注意:这使用()代替(Test)。它看起来很奇怪,但它会起作用。
  • 重要提示:您必须提供所有iVar,且必须按照确切的顺序排列,否则可能会导致意外行为(如随机崩溃)。

答案 1 :(得分:1)

我不确定是否明智地让单元测试检查对象是如何做私事的,因为这会使更改如何类执行其功能变得更加困难

如果您的函数更改了私有属性,则此更改应该影响任何其他公共属性/函数的行为。如果此属性的值不影响任何公共函数,为什么要使用此属性以及为什么要更改它?结论:如果函数A更改了私有属性的值,那么应该有一个函数B(可能与A相同),它会因为这种变化而改变行为。

函数A的规范不应该包含它设置私有属性x,但是它改变了B的行为:

  

规范:如果使用参数值x调用public TemporaryKey.pfx,那么`public int B {get;}应返回2 * x。

有几种方法可以实现这一点。您的测试不应测试它的实现方式。它应该测试规范。如果设计人员认为将x保存在文件而不是私有成员中会更好,那么仍然可以满足您的规范,但您的测试将失败。

因此,指定私有项的值会限制类的开发人员,并使将来的更改变得更加困难。

此外:在开发课程和测试之前,您应该正式定义规范,因此您不会知道哪些私有成员受到该功能的影响。测试应关注的是规范是否得到满足,而不是关于如何实现这些功能。