Xamarin TouchRunner挂起呼叫IOS第三方绑定

时间:2018-02-20 20:00:53

标签: xamarin xamarin.ios nunit

我正在尝试使用TouchRunner测试第三方API IOS绑定(更像是集成测试)。

示例API方法就是这个 -

 _client.AuthenticateWithUsername(username, token,
    () => { // Success Callback },
    () => { // NoConnection Callback },
    (obj) => { // Other Error Callback });

API调用时关闭并在后台执行一些工作然后最终进行上面的一个回调,我想用类似的东西来控制单元测试的流程 -

How can I unit test async methods on the UI Thread with Xamarin iOS TouchRunner

不幸的是,当我插入AutoResetEvent代码时,TouchRunner只是挂起而永远不会返回到GUI。

我还尝试使用TaskCompletionSource,如下所示 -

    public async Task<AuthResponse> AuthenticateUserAsync(string username, string password)
    {
        TaskCompletionSource<AuthResponse> tcs = new TaskCompletionSource<AuthResponse>();

        AuthResponse response = new AuthResponse { Success = false };

        LoginResponse loginResponse = await LoginUser(username, password);

        _client.AuthenticateWithUsername(username, loginResponse.token,
             () =>
               {
                   response.Success = true;
                   Console.WriteLine("Auth");
                   tcs.SetResult(response);
               },
               () => { tcs.SetResult(response); },
               obj => { tcs.SetResult(response); },
               obj => { tcs.SetResult(response); });

        return await tcs.Task;
    }

    [Test]
    public async void AuthenticateUserAsyncTest()
    {
        var auth = await AuthenticateUserAsync(_username, _password);

        Assert.IsTrue(auth.Success);
    }

调试器逐步完成,直到返回等待tcs.Task,然后导致类似的HUNG运行器。

我怎样才能弄清楚为什么会发生这种情况?

由于这不起作用,我接着使用这样的代码 -

 _client.AuthenticateWithUsername(_username, loginResponse.token,
     () =>
     {
         Assert.Pass("This crashes the runner");
         Assert.True(true);  // This DOES NOT!
     },
     () =>
     {
         // This will crash runner also
         Assert.Fail("NoConnection");
     },
     (InvalidTokenError obj) =>
     {
         Assert.Fail("InvalidToken" + obj.Description);
     },
     (ClientError obj) =>
     {
         Assert.Fail("ClientError" + obj.Description);
     });

正如您所看到的,流程最终(可理解),运行测试,运行客户端调用,测试结束方法完成,显示测试成功,然后回调返回并且断言被调用,这使应用程序崩溃,我们假设是因为跑步者已经完成了测试,为什么一个断言工作和其他我不知道的崩溃。

所以,

  • 我是以正确的方式接近这个吗?
  • 可能会在第三方API中发生导致这些方法挂起的事情吗?我该如何调试?

2 个答案:

答案 0 :(得分:1)

感谢@Nkosi,这是一个很好的建议,我忘了在原始测试期间添加,当我使用异步任务运行代码而不是无效时,我从TouchRunner立即阻止,甚至没有添加任何其他代码API调用!我想这是一个红旗,但使用async void&#34;似乎&#34;允许&#34;标准&#34;异步测试,所以我继续进行,然后在上面的循环中结束。

由于TouchRunner在很长一段时间内没有更新,我花了很多时间在论坛和堆栈中尝试使用XUnit重新创建测试项目。

其他一些有用的链接是 -

结果:我很高兴地说上述代码现在适用于TaskCompletionSource和AutoResetTask场景

我现在可以安全地测试基于事件的API:)

我只想确保其他用户了解这一点。 谢谢你的帮助。

答案 1 :(得分:0)

一个观察结果是测试应该是async Task而不是async void

public async Task AuthenticateUserAsyncTest() {
    //...code removed for brevity.
}

async void是一个火,忘记所以抛出的任何异常都不会在当前上下文中发生,所以它们不会被捕获。

参考Async/Await - Best Practices in Asynchronous Programming