【问题标题】:Unity: Testing async functions that returns IPromiseUnity:测试返回 IPromise 的异步函数
【发布时间】:2020-11-22 01:23:50
【问题描述】:

我是 Unity 的新手,发现它的异步管理有点难以处理,所以我使用 IPromises : https://github.com/Real-Serious-Games/C-Sharp-Promise 这让我可以使用

MyAsyncFunction.Then(() => 
{
  // What happened if everything went OK
}).Catch(error =>
{
  // What happend if an exception was thrown
})

我也在使用 Unity Rest Client,它使用IPromises:https://github.com/proyecto26/RestClient

我正在使用 NUnit 进行测试,似乎 它必须在测试异步代码时返回一个任务

在我的代码中,我使用 Unity Rest Client 并将我的 Assert 放在 Then 部分中。问题是 NUnit 不等待请求,因此不执行断言。

这是我的代码:

        [Test]
        public async Task TestLogin()
        {
            _network.SendCode(_password)
                .Then(authResp =>
                {
                    Assert.True(authResp.IsSuccessful);
                    Assert.IsNotNull(authResp.Name);
                    Assert.IsNotNull(authResp.Surname);
                    Assert.IsNotNull(authResp.AccessToken);
                    Assert.AreEqual(authResp.AccessToken, _tokenStorage.RetrieveAccessToken());
                });
        }

这里是SendCode的实现:

        public IPromise<AuthenticationResponse> SendCode(string code)
        {
            var promise = new Promise<AuthenticationResponse>();

            RestClient.Post("/api/login", new Credentials(code))
                .Then(response =>
                {
                    EditorUtility.DisplayDialog("JSON", JsonUtility.ToJson(response, true), "Ok");
                    promise.Resolve(new AuthenticationResponse("", "", true, "", "200"));
                })
                .Catch(error =>
                {
                    EditorUtility.DisplayDialog("ERROR", JsonUtility.ToJson(error, true), "Ok");
                    promise.Reject(new Exception("Error when logging"));
                });

            return promise;
        }

我看到了两种可能性:

  1. 在测试中将IPromise 转换为Task
  2. 更改SendCode 的实现,使其返回Task。并放弃使用 UnityRestClient :'(

如果有人知道如何做第一种可能性,或者能给我一点指导来做第二种可能性,那就太棒了。

【问题讨论】:

  • 你是如何运行测试的?在 Unity Test Runner 中或以其他方式。您使用的是哪个版本的 Unity?

标签: c# .net unity3d asynchronous testing


【解决方案1】:

我在查看 C-Sharp-Promise git respository 时遇到了一个名为 Not Usable inside Tasks? 的问题。其中一个 cmets 包含一个通过使用 TaskCompletionSource 将 Promise 与异步方法一起使用的示例,如下所示:

private Task AuthenticateAsync()
{
    var tcs = new TaskCompletionSource<object>();

    RestClient.Post<signInResponse_model>(someUri, someString)
        .Then(res =>
        {
            currentIDToken = res.idToken;
            currentUID = res.idToken;

            tcs.SetResult(null);
        })
        .Catch(error =>
        {
            Debug.LogException(error);
            tcs.SetException(error);
        });

    return tcs.Task;
}

另外,评论的作者指出了一点:

虽然从技术上讲,可以将 Promise 与 async/await 一起使用 代码,你永远不应该这样做。选择一种方法,全力以赴 路。

我认为说它应该永远这样做是不公平的,但如果可能的话,避免这种情况是公平的。我认为在你的情况下,如果你真的想使用 Unity Rest Client,你别无选择,只能将它们结合起来。但是,我认为从 Unity 应用程序中访问 REST 服务并不是一个不寻常的用例,因此,通过一些研究,如果您没有设置使用 Unity Rest Client,应该可以找到使用任务的替代方法.

【讨论】:

    猜你喜欢
    • 2017-03-23
    • 2022-01-20
    • 2019-07-09
    • 1970-01-01
    • 2014-02-08
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    相关资源
    最近更新 更多