如何为C# Azure Function编写单元测试?

3

我最近开始写一些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 方法中 NEW 了该实例。
我看到了下面的页面,使用 DI 来解决这个问题,但我不知道如何正确编写单元测试。
所以你能给我展示一个例子吗?

2
将您想要测试的逻辑重构为单独的方法或类怎么样?Azure Functions 只是将您的逻辑转换成端口。您真正想要测试的是实际逻辑。 - Wouter de Kort
@ WouterdeKort 是的,我创建了几个方法,但这些都是私有方法。所以我只能从测试类访问Run方法。我不想在此单元测试期间发送事件,因为单元测试将每次合并其他分支时运行。 - Capotasto
1
我不确定你所说的发送事件是什么意思。我建议阅读这本书https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/。这本书教你如何找到代码中的接缝,从而隔离行为并测试重要内容。你的代码在私有方法中是很好的,但是将这些私有方法提取到它们自己的类中,并在公共方法中传递所有需要的信息以进行测试呢? - Wouter de Kort
每次记录日志创建一个新的 TelemetryClient 实例代价很高,因此最好只实例化一次。我很好奇你是如何模拟 TraceWriterExecutionContext 的? - Mikhail Shilkov
@WouterdeKort 谢谢你分享书籍信息,我稍后会阅读它。 “我不确定你发送事件的意思是什么。” -> 我需要在每个函数中发送一个事件到Application Insight,例如“启动TaskA”。但我不想在测试期间这样做。因此,我认为我需要模拟TelemetryClient#TrackEvent - Capotasto
显示剩余4条评论
1个回答

5
首先,Azure Functions支持开箱即用的Application Insights。 Azure Functions现在可以与Application Insights直接集成 因此,我不建议您直接在代码中实现TelemetryClient。相反,将您的TraceWriter参数替换为ILogger,以从Application Insights中获得好处。
然而,如果您真的想在代码中使用TelemetryClient,我建议创建一个包装器接口,例如ITelemetryClientWrapper,实现它并通过依赖注入方法进行注入。
我已经写了一篇关于Azure Functions周围的依赖注入的博客文章: Azure Functions与IoC容器

ilogger会直接进入应用洞察吗? - Alex Gordon
只要您将仪表板密钥放入应用程序设置中,ILogger就可以捕获所有日志并将其发送到Application Insights。@l--''''''---------'''''''''''' - justinyoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接