【问题标题】:How can I unit-test init methods in Objective-C?如何在 Objective-C 中对 init 方法进行单元测试?
【发布时间】:2013-10-30 00:17:33
【问题描述】:

我正在使用新的 XCTest 框架在 Xcode 5 中对 Mac 应用程序进行单元测试。具体来说,我正在尝试测试一个类是否实现了一个(尚未编写!)- (id)initWithStream:(NSInputStream)stream 方法。所以我的测试开始了:

- (void)testInitWithStream
{
  // Should have an init method named initWithStream:
  XCTAssertTrue([[MYParser alloc]
                 respondsToSelector:@selector(initWithStream:)],
                @"'initWithStream:' not implemented.");

效果很好;测试目前按预期失败。这是下一部分,它试图运行尚未编写的方法,这让我很伤心:

  // Should return nil if no valid stream is passed
  XCTAssertNil([[MYParser alloc]
                  performSelector:@selector(initWithStream:)
                  withObject:nil], 
                 @"should get nil on 'initWithStream:' with no stream.");

Xcode 给我一个错误“PerformSelector 命名了一个保留对象的选择器。”我正在使用performSelector:withObject:,因为尝试直接调用选择器会导致错误“没有可见的@interface for 'MYParser' 声明选择器'initWithStream:'。”

我的测试套件关闭了GCC_WARN_UNDECLARED_SELECTOR,但这些是错误,而不是警告。当测试需要涵盖方法可能尚未实现(即使作为定义)的情况时,如何测试对象的 init 方法?

该方法可能尚未实现,因为我先编写测试;这是正确的,还是我应该先写我的类定义,然后是我的测试,然后是实际的实现? (我正在寻找关于这一点的共识和最佳实践,而不仅仅是意见。)

【问题讨论】:

    标签: objective-c xcode unit-testing xctest


    【解决方案1】:

    如果您进行先测试开发,则无需测试respondsToSelector:@selector(initWithStream:)。在您的测试套件中直接调用initWithStream: 最初不会编译。这是您在编写新代码之前应该修复的失败测试。你如何解决它?通过实现方法:

    - (instancetype)initWithStream:(id)stream {
        return [super init];
    }
    

    您的测试现在可以编译,这比以前好一点。但是运行测试会失败,因为显然实现并没有做你正在测试的事情。现在编写更多代码以使测试真正通过:

    - (instancetype)initWithStream:(id)stream {
        if (!stream) {
            return nil;
        }
        return [super init];
    }
    

    接下来,您可以测试stream 不是nil,这将失败,因此您需要编写更多代码来修复它。

    【讨论】:

      猜你喜欢
      • 2014-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      相关资源
      最近更新 更多