0

我正在制作一个类,它将作为脚本加载的一个门面。此类将与加载了磁盘上的 HTML 和 JS 文件的无头 UIWebView 进行交互。

我目前正在单元测试环境中执行所有操作,看起来 UIWebView 拒绝加载任何内容。这是我的代码的样子:

WebView 初始化

self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,0,0)];
self.webView.delegate = self;
[self loadScriptingCore];

脚本加载器:

- (void)loadScriptingCore
{
    NSURLRequest *loadRequest = [NSURLRequest requestWithURL:[self scriptingCoreIndex]];
    [self.webView loadRequest:loadRequest];
    NSLog([self inspectDom]);
}

- (NSURL *) scriptingCoreIndex  
{
    NSString *indexPath = [[NSBundle mainBundle] pathForResource:@"scripting-core" ofType:@"html" inDirectory:@"www"];
    NSLog([NSString stringWithFormat:@"Scripting Core Index: %@", indexPath]);
    return [NSURL fileURLWithPath:indexPath];
}

- (NSString *)inspectDom
{
    return [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML;"];
}

HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Scripting Core</title>
</head>
<body>
   <div id="element">
       Hello
    </div>
</body>
</html>

inspectDom 方法只返回

<html><head></head><body></body></html>

Thich 向我表明,webView 没有发生任何事情。此外,委托方法似乎不会触发 webViewDidStartLoad、webViewDidFinishLoad 和 webViewDidFailLoad。

任何建议,将不胜感激

谢谢!

4

3 回答 3

2

测试问题的要点是 UIWebView 加载是异步的。我在发出请求后尝试了 [NSThread sleepForTimeInterval],但这还不够。显然,主线程需要处于活动状态才能使 UIWebView 异步加载。

通过使用这种异步测试机制,我能够让我的单元测试通过:

https://github.com/akisute/SenAsyncTestCase

这段代码使用 NSRunLoop 来旋转运行循环,同时保持主线程处于活动状态——有点像伪睡眠。在请求脚本加载后,在我的测试中添加 1/10 秒的等待会导致 DOM 被正确加载并触发委托事件。

[self waitForTimeout: 0.1];
于 2013-01-02T05:59:55.683 回答
0

确保在您的 @ 实现中将类设置为委托

@implementation myclass:parent <UIWebViewDelegate>

的输出是NSLog([NSString stringWithFormat:@"Scripting Core Index: %@", indexPath]);什么?

于 2013-01-02T02:19:28.900 回答
0

在 Swift 中,如果你还在使用 UIWebView,并且你想在调用 load(data: ...) 之后测试它的内容,你可以尝试以下方法:

class TestCase: XCTestCase {
  var testDelegate: TestDelegate()
  lazy var loadExpectation: XCTestExpectation = { return self.expectation(description: "waiting") }()

  func testSomething() {
    testDelegate.expectation = loadExpectation

    webViewUnderTest.delegate = testDelegate
    webViewUnderTest.load(data: ...)

    waitForExpectations(timeout: 5) { (error) in
      dump(error)
    }

    assert(...)
  }
}

class TestDelegate: NSObject, UIWebViewDelegate {
  var expectation: XCTestExpectation?

  func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
      return true
  }

  func webViewDidFinishLoad(_ webView: UIWebView) {
      expectation?.fulfill()
  }
}
于 2018-03-27T14:17:32.403 回答