【发布时间】:2016-02-22 06:35:33
【问题描述】:
我有一个 MVC Web 应用程序,并且我正在使用 Simple Injector for DI。几乎我所有的代码都包含在单元测试中。但是,现在我已经在一些控制器中添加了一些遥测调用,我在设置依赖项时遇到了麻烦。
遥测调用用于将指标发送到 Microsoft Azure 托管的 Application Insights 服务。该应用程序不在 Azure 中运行,只是一个带有 ISS 的服务器。 AI 门户会告诉您有关应用程序的各种信息,包括您使用遥测库发送的任何自定义事件。因此,控制器需要一个 Microsoft.ApplicationInsights.TelemetryClient 的实例,该实例没有接口并且是一个密封类,具有 2 个构造函数。我试着像这样注册它(混合生活方式与这个问题无关,我只是为了完整性而将它包括在内):
// hybrid lifestyle that gives precedence to web api request scope
var requestOrTransientLifestyle = Lifestyle.CreateHybrid(
() => HttpContext.Current != null,
new WebRequestLifestyle(),
Lifestyle.Transient);
container.Register<TelemetryClient>(requestOrTransientLifestyle);
问题在于,由于 TelemetryClient 有 2 个构造函数,因此 SI 会抱怨并且验证失败。我发现一篇文章展示了如何覆盖容器的构造函数解析行为,但这似乎很复杂。首先我想备份并问这个问题:
如果我不使 TelemetryClient 成为注入依赖项(只需在类中创建一个新的依赖项),那么该遥测数据是否会在每次运行单元测试时发送到 Azure,从而创建大量错误数据?或者 Application Insights 是否足够聪明,可以知道它正在单元测试中运行,而不是发送数据?
对此问题的任何“见解”将不胜感激!
谢谢
【问题讨论】:
-
我无法帮助解决问题的 AI 方面,但只需注册一个针对特定构造函数的委托即可完成注册:
container.Register(() => new TelemetryClient(/*whatever constructor you want to target*/), requestOrTransientLifestyle);。另请查看DefaultScopedLifestyle -
对于单元测试,您应该真正定义自己的 TelemetryClient 抽象,您可以根据需要进行模拟。单元测试不应该与 Azure 对话。
-
您的自定义混合范围让我担心。将 Web 请求生活方式与短暂的生活方式混合在一起通常不是一个好的做法。它可以解释为什么你需要这种混合生活方式?
-
@Steven - 创建混合范围是为了处理 signalR 需要访问控制器正在使用的相同服务,但该服务已经超出范围。这是由另一位开发人员完成的,由于我的应用未使用 signalR,因此我已将其删除。
标签: c# unit-testing azure simple-injector azure-application-insights