HTTP 服务器在 Cocoa 应用程序中工作,但在测试用例中不起作用——运行循环问题?

发布于 2024-10-28 23:58:29 字数 2375 浏览 0 评论 0原文

我正在尝试向此 SimpleHTTPServer 示例 添加 GHUnit 测试用例。该示例包括一个对我来说运行良好的 Cocoa 应用程序。但我无法在测试用例中复制该行为。

这是测试类:

#import <GHUnit/GHUnit.h>
#import "SimpleHTTPServer.h"


@interface ServerTest : GHTestCase
{
    SimpleHTTPServer *server; 
}
@end


@implementation ServerTest

-(void)setUpClass
{
    [[NSRunLoop currentRunLoop] run]; 
}

- (NSString*)requestToURL:(NSString*)urlString error:(NSError**)error
{
    NSURL *url = [NSURL URLWithString:urlString]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:1]; 
    NSURLResponse *response = nil; 
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error]; 
    NSString *page = nil; 
    if (error == nil)
    {
        NSStringEncoding responseEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)[response textEncodingName]));
        page = [[NSString alloc] initWithData:data encoding:responseEncoding]; 
        [page autorelease];
    }
    return page; 
}

- (void)testPortReuse
{
    unsigned int port = 50001; 
    NSError *error = nil; 
    NSString *path, *url; 

    server = [[SimpleHTTPServer alloc] initWithTCPPort:port delegate:self]; 
    sleep(10); 
    path = @"/x/y/z"; 
    url = [NSString stringWithFormat:@"http://localhost:%u%@", port, path]; 
    [self requestToURL:url error:&error]; 
    GHAssertNil(error, @"%@ : %@", url, error); 
    [server release]; 
}

- (void)processURL:(NSURL *)path connection:(SimpleHTTPConnection *)connection
{
    NSLog(@"processURL"); 
}

- (void)stopProcessing
{
    NSLog(@"stopProcessing"); 
}

@end

我尝试通过 NSURLRequest 发送请求,也尝试通过网络浏览器(在睡眠期间)发送请求。委托方法 -processURL-stopProcessing 永远不会被调用。问题似乎是 SimpleHTTPServer -initWithTCPPort:delegate: 中的 [fileHandle acceptConnectionInBackgroundAndNotify] 不会导致任何 NSFileHandleConnectionAcceptedNotifications 到达 NSNotificationCenter - 所以我怀疑涉及运行循环的问题。

问题似乎出在 NSFileHandle 上,而不是 NSNotificationCenter 上,因为当将 [nc postNotificationName:NSFileHandleConnectionAcceptedNotification object:nil] 添加到 initWithTCPPort:delegate: 的末尾时, NSNotificationCenter 确实收到了通知。

I'm trying to add a GHUnit test case to this SimpleHTTPServer example. The example include a Cocoa application that works fine for me. But I can't duplicate the behavior in a test case.

Here is the test class:

#import <GHUnit/GHUnit.h>
#import "SimpleHTTPServer.h"


@interface ServerTest : GHTestCase
{
    SimpleHTTPServer *server; 
}
@end


@implementation ServerTest

-(void)setUpClass
{
    [[NSRunLoop currentRunLoop] run]; 
}

- (NSString*)requestToURL:(NSString*)urlString error:(NSError**)error
{
    NSURL *url = [NSURL URLWithString:urlString]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:1]; 
    NSURLResponse *response = nil; 
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error]; 
    NSString *page = nil; 
    if (error == nil)
    {
        NSStringEncoding responseEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)[response textEncodingName]));
        page = [[NSString alloc] initWithData:data encoding:responseEncoding]; 
        [page autorelease];
    }
    return page; 
}

- (void)testPortReuse
{
    unsigned int port = 50001; 
    NSError *error = nil; 
    NSString *path, *url; 

    server = [[SimpleHTTPServer alloc] initWithTCPPort:port delegate:self]; 
    sleep(10); 
    path = @"/x/y/z"; 
    url = [NSString stringWithFormat:@"http://localhost:%u%@", port, path]; 
    [self requestToURL:url error:&error]; 
    GHAssertNil(error, @"%@ : %@", url, error); 
    [server release]; 
}

- (void)processURL:(NSURL *)path connection:(SimpleHTTPConnection *)connection
{
    NSLog(@"processURL"); 
}

- (void)stopProcessing
{
    NSLog(@"stopProcessing"); 
}

@end

I've tried sending requests via NSURLRequest and also (during the sleep) via a web browser. The delegate methods -processURL and -stopProcessing are never called. The problem seems to be that [fileHandle acceptConnectionInBackgroundAndNotify] in SimpleHTTPServer -initWithTCPPort:delegate: is not causing any NSFileHandleConnectionAcceptedNotifications to reach the NSNotificationCenter -- so I suspect a problem involving run loops.

The problem seems to be with the NSFileHandle, not the NSNotificationCenter, because when [nc postNotificationName:NSFileHandleConnectionAcceptedNotification object:nil] is added to the end of initWithTCPPort:delegate:, the NSNotificationCenter does get the notification.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烂柯人 2024-11-04 23:58:29
if (error == nil)

应该是:

if (data != nil)

error 这里是传入的指向 NSError* 的指针 - 只有当调用者传递 nil 而不是对 NSError* 对象的引用时,它才会是 nil,这不是你的-testPortReuse 方法可以。

取消引用它也是不正确的(如 if (*error == nil) 所示),因为错误参数不能保证在出错时设置为 nil。返回值指示错误情况,并且仅当存在错误时,错误参数中返回的值才有意义或可靠。始终检查返回值以确定是否发生错误,然后仅在确实出现错误时才检查错误参数以获取详细信息。

换句话说,正如上面所写,您的 -requestToURL:error: 方法无法处理成功。很像查理辛。 :-)

if (error == nil)

That should be:

if (data != nil)

error here is the passed-in pointer to an NSError* - it will only be nil if the caller passed nil instead of a reference to an NSError* object, which isn't what your -testPortReuse method does.

It would also be incorrect to dereference it (as in if (*error == nil)), because error arguments are not guaranteed to be set to nil upon error. The return value indicates an error condition, and the value returned in the error argument is only meaningful or reliable if there is an error. Always check the return value to determine if an error happened, then check the error parameter for details only if something did in fact go wrong.

In other words, as it's written above, your -requestToURL:error: method is incapable of handling success. Much like Charlie Sheen. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文