Как написать модульный тест для функции Azure v1 - PullRequest
0 голосов
/ 19 марта 2019

Я написал функцию Azure v1 HttpTrigger, которая получает данные клиента и транзакции от нашего API-сервиса, есть только один параметр, который является «частотой», который также является необязательным, поэтому, когда функция запускается, она получает подробности, а затем получает транзакции. для каждой информации о розничном продавце и возвращает список комиссионных за транзакции для каждого розничного торговца, я хочу написать модульный тест для своей функции, но я не могу увидеть хороший пример для моего сценария. Может ли кто-нибудь дать мне пример модульного теста (с moq если возможно), вот пример кодовой базы функции:

[FunctionName("FunctionTest1")]
public static async Task<HttpResponseMessage> 
Run([HttpTrigger(AuthorizationLevel.Function)]HttpRequestMessage req, ILogger log) {
        log.LogInformation("C# HTTP trigger function processed a request.");
        #region Properties
        string Frequency = req.GetQueryNameValuePairs().FirstOrDefault(q => string.Compare(q.Key, "frequency", true) == 0).Value;
        #endregion

        log.LogInformation("Getting client details from MongoDB");
        Process of Getting ClientDetails

        log.LogInformation("Get and compute Transaction Fee foreach retailers from client details");
        Process of Getting And Computing Transactions for each retailers (NOTE Took too much time)


        log.LogInformation("Return results response");
        return txnList == null
            ? new HttpResponseMessage(HttpStatusCode.InternalServerError) {
                Content = new StringContent(JsonConvert.SerializeObject("Error getting data from server"), Encoding.UTF8, "application/json")
            } : new HttpResponseMessage(HttpStatusCode.OK) {
                Content = new StringContent(JsonConvert.SerializeObject(txnList, Newtonsoft.Json.Formatting.Indented), Encoding.UTF8, "application/json")
            };
    } 

Рекомендации по тестированию модулей, которые я пробовал: https://docs.microsoft.com/en-us/azure/azure-functions/functions-test-a-function
https://medium.com/@tsuyoshiushio/writing-unit-test-for-azure-durable-functions-80f2af07c65e

Что я пробовал:

[TestMethod]
    public async Task Response_Should_Not_Null()
    {
        var request = new HttpRequestMessage();

        var logger = Mock.Of<ILogger>();

        var response = await FunctionTest1.Run(request, logger).ConfigureAwait(false);

        Assert.IsNotNull(response);
    }

Ошибки, которые я получил:
Нить 0x5580 вышла с кодом 0 (0x0).
Программа '[23748] dotnet.exe' вышла с кодом 0 (0x0).
Программа '[23748] dotnet.exe: Программа Trace' вышла с кодом 0 (0x0).

С уважением,
Нико

1 Ответ

0 голосов
/ 20 марта 2019

Здесь я даю пример тестового блока с вспомогательной функцией.

Тестовый пример: - Request_With_Query Вспомогательная функция: - HttpReuqestSetup (путем mokcing HttprequestObject)

У меня есть заметка, издевающаяся над объектом регистраторакак это может помочь мне с предоставлением полезной информации

Вот так выглядит моя функция

 public static class HttpTrigger
    {
        [FunctionName("HttpTrigger")]
        public async static Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }

    }

, и вот так выглядит мой тестовый класс:

[TestClass]
    public class HttpTriggerTest : FunctionTestHelper.FunctionTest
    {
        [TestMethod]
        public async Task Request_With_Query()
        {
            var query = new Dictionary<String, StringValues>();
            query.TryAdd("name", "ushio");
            var body = "";

            var result = await HttpTrigger.RunAsync(req: HttpRequestSetup(query, body), log: log);
            var resultObject = (OkObjectResult)result;
            Assert.AreEqual("Hello, ushio", resultObject.Value);

        }

        [TestMethod]
        public async Task Request_Without_Query()
        {
            var query = new Dictionary<String, StringValues>();
            var body = "{\"name\":\"yamada\"}";

            var result = await HttpTrigger.RunAsync(HttpRequestSetup(query, body), log);
            var resultObject = (OkObjectResult)result;
            Assert.AreEqual("Hello, yamada", resultObject.Value);

        }

        [TestMethod]
        public async Task Request_Without_Query_And_Body()
        {
            var query = new Dictionary<String, StringValues>();
            var body = "";
            var result = await HttpTrigger.RunAsync(HttpRequestSetup(query, body), log);
            var resultObject = (BadRequestObjectResult)result;
            Assert.AreEqual("Please pass a name on the query string or in the request body", resultObject.Value);
        }
    }

Вот классы Helper

using Microsoft.AspNetCore.Http;использование Microsoft.AspNetCore.Http.Internal;использование Microsoft.Azure.WebJobs;использование Microsoft.Azure.WebJobs.Host;использование Microsoft.Extensions.Primitives;используя Moq;используя Систему;using System.Collections.Generic;используя System.IO;используя System.Net.Http;используя System.Text;используя System.Threading;используя System.Threading.Tasks;

namespace FunctionTestHelper
{
    public abstract class FunctionTest
    {

        protected TraceWriter log = new VerboseDiagnosticsTraceWriter();

        public HttpRequest HttpRequestSetup(Dictionary<String, StringValues> query, string body)
        {
            var reqMock = new Mock<HttpRequest>();

            reqMock.Setup(req => req.Query).Returns(new QueryCollection(query));
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(body);
            writer.Flush();
            stream.Position = 0;
            reqMock.Setup(req => req.Body).Returns(stream);
            return reqMock.Object;
        }

    }

    public class AsyncCollector<T> : IAsyncCollector<T>
    {
        public readonly List<T> Items = new List<T>();

        public Task AddAsync(T item, CancellationToken cancellationToken = default(CancellationToken))
        {

            Items.Add(item);

            return Task.FromResult(true);
        }

        public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            return Task.FromResult(true);
        }
    }
}

public class VerboseDiagnosticsTraceWriter : TraceWriter
    {

        public VerboseDiagnosticsTraceWriter() : base(TraceLevel.Verbose)
        {

        }
        public override void Trace(TraceEvent traceEvent)
        {
            Debug.WriteLine(traceEvent.Message);
        }
    }

Используйте аналогичный шаблон в вашем случае, вы должны быть в состоянии мирно издеваться и писать UT.

Надеюсь, это поможет.

...