【发布时间】: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的新实例的成本很高,因此您应该实例化一次。我很好奇你是如何模拟TraceWriter和ExecutionContext的? -
@Mikhail 是的,我只在调用 Run 方法时创建了一次
TelemetryClient。您可以在下面找到模拟TraceWriter和ExecutionContext的方法。 devxp.blogspot.ca/2017/07/…
标签: c# unit-testing dependency-injection azure-functions azure-application-insights