首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSLog输出测试

NSLog输出测试
EN

Stack Overflow用户
提问于 2016-02-05 11:48:14
回答 2查看 1.8K关注 0票数 7

我正在编写一个框架,其中还包括一个可以在运行时启用/禁用的简单记录器。由于我希望尽可能多地对框架进行单元测试,所以我也希望测试记录器是否正确工作。

记录器只是通过NSLog进行日志记录。现在,我需要测试输出是否真正符合预期(即,它是否真的日志并是正确格式的输出)。我无法找到一种使用Xcode的XCTest框架来实现这个目标的方法。

我可以修改记录器,以便它在测试时不使用NSLog,但我认为这很容易出错。那么,是否有更好的方法来检查NSLog输出?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-11 09:12:02

我编写了一个实用工具类来解决这个问题,该类将文件描述符重定向到文件,并能够重置此重定向:

代码语言:javascript
复制
@interface IORedirector : NSObject

- (instancetype)initWithFileDescriptor:(int)fileDescriptor targetPath:(NSURL *)fileURL flags:(int)oflags mode:(mode_t)mode;

- (void)reset;

@end

@implementation IORedirector
{
    int _fileDescriptor;
    int _savedFileDescriptor;
}

- (instancetype)initWithFileDescriptor:(int)fileDescriptor targetPath:(NSURL *)fileURL flags:(int)oflags mode:(mode_t)mode
{
    _savedFileDescriptor = dup(fileDescriptor);
    if (_savedFileDescriptor == -1) {
        NSLog(@"Could not save file descriptor %d: %s", fileDescriptor, strerror(errno));
        return nil;
    }

    int tempFD = open(fileURL.path.fileSystemRepresentation, oflags, mode);
    if (tempFD == -1) {
        NSLog(@"Could not open %@: %s", fileURL.path, strerror(errno));
        close(_savedFileDescriptor);
        return nil;
    }

    if (close(fileDescriptor) == -1) {
        NSLog(@"Closing file descriptor %d failed: %s", fileDescriptor, strerror(errno));
        close(_savedFileDescriptor);
        close(tempFD);
        return nil;
    }

    if (dup2(tempFD, fileDescriptor) == -1) {
        NSLog(@"Could not replace file descriptor %d with new one for %@: %s", fileDescriptor, fileURL.path, strerror(errno));
        close(_savedFileDescriptor);
        close(tempFD);
        return nil;
    }

    _fileDescriptor = fileDescriptor;
    close(tempFD);

    return self;
}

- (void)dealloc
{
    [self reset];
}

- (void)reset
{
    if (_savedFileDescriptor == -1) return;

    if (close(_fileDescriptor) == -1) {
        NSLog(@"Closing file descriptor %d failed: %s", _fileDescriptor, strerror(errno));
        return;
    }

    if (dup2(_savedFileDescriptor, _fileDescriptor) == -1) {
        NSLog(@"Could not restore file descriptor %d: %s", _fileDescriptor, strerror(errno));
        return;
    }

    close(_savedFileDescriptor);
    _savedFileDescriptor = -1;
}

@end

初始化器返回有效实例(重定向已建立)或nil。调用reset立即恢复重定向。

初始化程序和reset都可能失败并“丢失”原始文件描述符,但是窗口很小而且不太可能。这可能只有在多线程应用程序中使用这个类时才有意义(我不这么做),所以如果您打算在多线程环境中使用这个类,您需要确保每次只能使用一个初始化器或reset来使用全局互斥体或其他东西。

使用这个类(当然,我有一个单独的测试用例),我可以将STDERR_FILENO重定向到一个文件,从而捕获NSLog的输出。这样,我就可以测试未经修改的日志记录类。

创建临时文件的适当路径是留给读者的练习。

票数 0
EN

Stack Overflow用户

发布于 2016-02-05 11:53:36

有记录器输出字符串。让另一个对象打印这些。这样,您就可以对第一个对象和第二个对象分别进行单元测试。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35223468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档