【问题标题】:How do I write Unit Test for C# Azure Function?如何为 C# Azure 函数编写单元测试?
【发布时间】:2018-03-06 18:37:43
【问题描述】:

这些天我刚开始编写一些 C# 函数代码,我必须使用 Application Insight(AI) 发送跟踪事件。这是我编写的示例代码。

namespace BlobTrigger {
    public static class Main {
        private static string sKey = TelemetryConfiguration.Active.InstrumentationKey = System.Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", EnvironmentVariableTarget.Process);
        private static TelemetryClient sTelemetry;
       [FunctionName("BlobTrigger")]
       public static void Run(
            [BlobTrigger("upload/{name}.wav")] Stream myBlob,
            string name,
            Microsoft.Azure.WebJobs.ExecutionContext context,
            TraceWriter log) {

            sTelemetry  = new TelemetryClient() { InstrumentationKey = sKey };
            sTelemetry.Context.Operation.Id = context.InvocationId.ToString();
            sTelemetry.Context.Operation.Name = name;
            sTelemetry.TrackEvent("File is uploaded");
            .....
    }
}

这个功能很好用。但我的问题是为此编写一些单元测试。我为 Run 方法的四个参数创建了一些模拟类,并已经覆盖了它的方法。这很容易。但我不知道如何模拟 TelemetryClient#TrackEvent,因为我在 Run 方法中新建了该实例。

我看到下面的页面为此使用了 DI,但我不明白如何正确编写单元测试。

Using Application Insights with Unit Tests?

那么你能告诉我这个示例单元测试代码吗?

【问题讨论】:

  • 如何将您实际想要测试的逻辑重构为单独的方法或类? Azure Functions 只是您的逻辑的一个端口。这是您要测试的实际逻辑。
  • @WouterdeKort 是的,我创建了几个方法,但这些都是私有方法。所以我只能从测试类访问Run 方法。我不想在这个单元测试期间发送事件,因为单元测试每次从其他分支合并时都会运行。
  • 我不确定您所说的发送事件是什么意思。我建议阅读amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/… 这本书,这本书教你如何找到代码中的接缝,在那里你可以隔离行为并只测试重要的部分。您的代码在私有方法中这一事实很好,但是将这些私有方法提取到它们自己的类中并在可以测试的公共方法中传递所有需要的信息呢?
  • 为每个日志创建一个TelemetryClient 的新实例的成本很高,因此您应该实例化一次。我很好奇你是如何模拟 TraceWriterExecutionContext 的?
  • @Mikhail 是的,我只在调用 Run 方法时创建了一次 TelemetryClient。您可以在下面找到模拟 TraceWriterExecutionContext 的方法。 devxp.blogspot.ca/2017/07/…

标签: c# unit-testing dependency-injection azure-functions azure-application-insights


【解决方案1】:

首先,Azure Functions 支持开箱即用的 Application Insights。

Azure Functions now has direct integration with Application Insights

因此,我不建议您在代码中直接实现TelemetryClient。相反,请将您的 TraceWriter 参数替换为 ILogger 以从 Application Insights 中受益。

但是,如果您真的想在代码中使用TelemetryClient,我建议您创建一个像ITelemetryClientWrapper 这样的包装接口,实现它并通过依赖注入方法注入它。

我写了一篇关于 Azure Functions 依赖注入的博文:

Azure Functions with IoC Container

【讨论】:

  • ilogger 会直接进入 appinsights 吗?
  • @l--''''''------'''''''''''' 是的,只要你把 Instrumentation 键输入应用程序设置,ILogger 捕获所有日志并将它们发送到 Application Insights
猜你喜欢
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2016-09-25
  • 1970-01-01
相关资源
最近更新 更多