Unity: тестирование асинхронных c функций, возвращающих IPromise - PullRequest
1 голос
/ 01 августа 2020

Я новичок в 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 для тестирования, и кажется, что он должен вернуть задачу при тестировании asyn c кода.

В моем коде я использую 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;
        }

Я вижу 2 возможности:

  1. Преобразование IPromise в Task в тесте
  2. Изменение реализация SendCode, чтобы он возвращал Task. И откажитесь от использования UnityRestClient : '(

Если кто-нибудь знает, как реализовать первый вариант или может дать мне небольшое руководство, чтобы выполнить второй, это было бы быть потрясающим.

1 Ответ

0 голосов
/ 13 августа 2020

Я искал C -Sharp-Promise git репозиторий и столкнулся с проблемой под названием Not Usable inside Tasks? . Один из комментариев включает пример использования обещания с помощью метода asyn c с использованием TaskCompletionSource , как показано ниже:

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;
}

Кроме того, автор комментария сделал заметным point:

Хотя технически возможно использовать обещания с кодом async / await, вы никогда не должны этого делать. Выберите один подход и go с ним полностью.

Я не думаю, что будет справедливо сказать, что это никогда не должно выполняться, но было бы справедливо сказать по возможности избежать этого. Я думаю, что в вашем случае, если вы действительно хотите использовать Unity Rest Client, у вас не будет другого выбора, кроме как объединить их. Однако я думаю, что доступ к службе REST из приложения Unity не является необычным вариантом использования, поэтому после некоторых исследований можно будет найти альтернативный подход, использующий задачи, если вы не настроены на использование клиента Unity Rest. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...