如何从单元测试类中访问静态变量?

时间:2016-06-18 15:07:22

标签: ios objective-c unit-testing

我的COURSE_NAME类实现文件中有一个静态变量School

标题文件:

@interface School {
  ...
}
@end

在实施档案中:

static NSString *COURSE_NAME = @"secret-course";
@implementation School
 ...
@end

我为School创建了单元测试类。

@interface SchoolTest : XCTestCase
@end

@implementation SchoolTest

- (void)setUp {
  [super setUp];
  ...
}

- (void)tearDown {
  ...
  [super tearDown];
}

- (void)testSomeFunc {
  // how can I access the static variable 'COURSE_NAME' 
  // in School implementation file?
}

有没有办法从单元测试类访问COURSE_NAME实现文件中定义的静态变量School,而不会将此静态变量暴露给School的公共接口

(如果答案是否定的话,那么,从单元测试类中访问类'静态变量的最佳做法是什么?如果唯一的解决方案是声明{{1}为了非静态,那么为我的测试用例重构代码的最佳做法是什么?通常COURSE_NAME是一个常量字符串,不会被更改。)

1 个答案:

答案 0 :(得分:1)

在Objective-C中无法访问C风格的静态变量,因为它们的名称是翻译单元的本地名称 - 这是一种说出.m文件的奇特方式。 COURSE_NAME的名称不可用于链接器,这意味着您无法在声明它们的.m文件之外访问它们。

您可以采用三种方法对依赖于静态变量的代码进行单元测试:

  1. 测试依赖COURSE_NAME变量的公共方法,并以间接方式检查变量是否具有正确的值。
  2. 创建一个非静态全局测试函数,返回变量的值,并在单元测试中使用该测试函数
  3. 在您的班级中添加一个类方法(在其名称前加+而不是-),并使用它来访问静态变量的值。
  4. 由于翻译单元静态变量对您的实现是私有的,因此#1提供了最佳方法,因此您的单元测试不依赖于您的类的实现细节。

    实施方法#1的实际方式取决于代码使用COURSE_NAME值的方式。

    例如,假设您使用COURSE_NAME作为必修课程的名称,该课程总是添加到学生想要学习的课程列表中,除非它已经在列表中。然后你应该编写一个单元测试,提供一个没有秘密课程的课程列表,在方法运行后获取更新的课程列表,并添加"secret-course"在结果中的检查。您还应该添加包含"secret-course"的其他测试,并验证在这种情况下是否添加了新课程。