Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将应用程序洞察与单元测试结合使用?_C#_Unit Testing_Azure_Simple Injector_Azure Application Insights - Fatal编程技术网

C# 将应用程序洞察与单元测试结合使用?

C# 将应用程序洞察与单元测试结合使用?,c#,unit-testing,azure,simple-injector,azure-application-insights,C#,Unit Testing,Azure,Simple Injector,Azure Application Insights,我有一个MVC web应用程序,我正在使用Simple Injector for DI。几乎我所有的代码都包含在单元测试中。然而,现在我在一些控制器中添加了一些遥测调用,设置依赖项时遇到了问题 遥测调用用于向Microsoft Azure托管的Application Insights服务发送度量。该应用程序没有在Azure中运行,只是一个带有ISS的服务器。AI门户告诉您有关应用程序的所有信息,包括使用遥测库发送的任何自定义事件。因此,控制器需要一个Microsoft.ApplicationIn

我有一个MVC web应用程序,我正在使用Simple Injector for DI。几乎我所有的代码都包含在单元测试中。然而,现在我在一些控制器中添加了一些遥测调用,设置依赖项时遇到了问题

遥测调用用于向Microsoft Azure托管的Application Insights服务发送度量。该应用程序没有在Azure中运行,只是一个带有ISS的服务器。AI门户告诉您有关应用程序的所有信息,包括使用遥测库发送的任何自定义事件。因此,控制器需要一个Microsoft.ApplicationInsights.TelemetryClient实例,该实例没有接口,是一个密封类,具有2个构造函数。我试着像这样注册它(混合生活方式与这个问题无关,我只是为了完整性而包括它):

//优先于web api请求范围的混合生活方式
var requestOrTransientLifestyle=lifety.CreateHybrid(
()=>HttpContext.Current!=null,
新WebRequestLifestyle(),
生活方式(短暂的);
容器。注册(请求者TransientLifestyle);
问题在于,由于TelemetryClient有2个构造函数,SI会投诉并失败验证。我发现了一篇文章,展示了如何重写容器的构造函数解析行为,但这似乎相当复杂。首先,我想提出一个问题:

如果我不将遥测客户端作为注入依赖项(只需在类中创建一个新的依赖项),那么在每次运行单元测试时,遥测会被发送到Azure,从而创建大量虚假数据吗?或者Application Insights是否足够聪明,可以知道它正在单元测试中运行,而不发送数据

对此问题的任何“见解”都将不胜感激

谢谢

Microsoft.ApplicationInsights.TelemetryClient,它没有接口,是一个密封类,具有2个构造函数

TelemetryClient
是一种框架类型,并且是

我发现了一篇文章,展示了如何重写容器的构造函数解析行为,但这似乎相当复杂

是的,这种复杂性是经过深思熟虑的,因为我们不想让人们创建具有多个构造函数的组件,因为这是非常复杂的

正如@qujck已经指出的,您不需要使用自动布线,只需进行以下注册:

container.Register<TelemetryClient>(() => 
    new TelemetryClient(/*whatever values you need*/),
    requestOrTransientLifestyle);
在这里,我假设
TelemetryClient
是线程安全的,可以作为单例工作。否则,您可以执行以下操作:

container.RegisterSingleton<ITelemetryLogger>(
    new TelemetryClientAdapter(() => new TelemetryClient(...)));
Microsoft.ApplicationInsights.TelemetryClient,它没有接口,是一个密封类,具有2个构造函数

TelemetryClient
是一种框架类型,并且是

我发现了一篇文章,展示了如何重写容器的构造函数解析行为,但这似乎相当复杂

是的,这种复杂性是经过深思熟虑的,因为我们不想让人们创建具有多个构造函数的组件,因为这是非常复杂的

正如@qujck已经指出的,您不需要使用自动布线,只需进行以下注册:

container.Register<TelemetryClient>(() => 
    new TelemetryClient(/*whatever values you need*/),
    requestOrTransientLifestyle);
在这里,我假设
TelemetryClient
是线程安全的,可以作为单例工作。否则,您可以执行以下操作:

container.RegisterSingleton<ITelemetryLogger>(
    new TelemetryClientAdapter(() => new TelemetryClient(...)));

如果您不想走抽象/包装的道路。在测试中,您可以简单地将AppInsights端点定向到一个模拟的轻量级http服务器(在ASP.NET核心中这是很平常的)

appInsightsSettings.json

    "ApplicationInsights": {
    "Endpoint": "http://localhost:8888/v2/track"
}

如果不想走抽象/包装路径,如何在ASP.NET核心中设置“TestServer”。在测试中,您可以简单地将AppInsights端点定向到一个模拟的轻量级http服务器(在ASP.NET核心中这是很平常的)

appInsightsSettings.json

    "ApplicationInsights": {
    "Endpoint": "http://localhost:8888/v2/track"
}

如何在ASP.NET Core中设置“TestServer”

另一个不走抽象路线的选项是在运行测试之前禁用遥测:


TelemetryConfiguration.Active.DisableTelemetry=true

另一个不走抽象路线的选项是在运行测试之前禁用遥测:


TelemetryConfiguration.Active.DisableTelemetry=true

Application Insights通过模拟
遥测通道对
遥测客户端进行单元测试

TelemetryChannel
实现了
ITelemetryChannel
,因此很容易模拟和注入。在本例中,您可以记录消息,然后稍后从断言的
Items
中收集消息

public class MockTelemetryChannel : ITelemetryChannel
{
    public IList<ITelemetry> Items
    {
        get;
        private set;
    }

    ...

    public void Send(ITelemetry item)
    {
        Items.Add(item);
    }
}

...

MockTelemetryChannel = new MockTelemetryChannel();

TelemetryConfiguration configuration = new TelemetryConfiguration
{
    TelemetryChannel = MockTelemetryChannel,
    InstrumentationKey = Guid.NewGuid().ToString()
};
configuration.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());

TelemetryClient telemetryClient = new TelemetryClient(configuration);

container.Register<TelemetryClient>(telemetryClient);
公共类MockTelemetryChannel:ITelemetryChannel
{
公共物品
{
得到;
私人设置;
}
...
公共无效发送(ITelemetry项)
{
项目。添加(项目);
}
}
...
MockTelemetryChannel=新的MockTelemetryChannel();
遥测配置=新的遥测配置
{
遥测通道=模拟遥测通道,
InstrumentationKey=Guid.NewGuid().ToString()
};
configuration.TelemetryInitializers.Add(新操作相关TelemetryInitializer());
遥测客户端遥测客户端=新的遥测客户端(配置);
容器寄存器(遥测客户端);

Application Insights通过模拟
遥测通道对
遥测客户端进行单元测试

TelemetryChannel
实现了
ITelemetryChannel
,因此很容易模拟和注入。在本例中,您可以记录消息,然后稍后从断言的
Items
中收集消息

public class MockTelemetryChannel : ITelemetryChannel
{
    public IList<ITelemetry> Items
    {
        get;
        private set;
    }

    ...

    public void Send(ITelemetry item)
    {
        Items.Add(item);
    }
}

...

MockTelemetryChannel = new MockTelemetryChannel();

TelemetryConfiguration configuration = new TelemetryConfiguration
{
    TelemetryChannel = MockTelemetryChannel,
    InstrumentationKey = Guid.NewGuid().ToString()
};
configuration.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());

TelemetryClient telemetryClient = new TelemetryClient(configuration);

container.Register<TelemetryClient>(telemetryClient);
公共类MockTelemetryChannel:ITelemetryChannel
{
公共物品
{
得到;
私人设置;
}
...
公共无效发送(ITelemetry项)
{
项目。添加(项目);
}
}
...
MockTelemetryChannel=新的MockTelemetryChannel();
遥测配置=新的遥测配置
{
遥测通道=模拟遥测通道,
InstrumentationKey=Guid.NewGuid().T
private TelemetryClient InitializeMockTelemetryChannel()
{
    // Application Insights TelemetryClient doesn't have an interface (and is sealed)
    // Spin -up our own homebrew mock object
    MockTelemetryChannel mockTelemetryChannel = new MockTelemetryChannel();
    TelemetryConfiguration mockTelemetryConfig = new TelemetryConfiguration
    {
        TelemetryChannel = mockTelemetryChannel,
        InstrumentationKey = Guid.NewGuid().ToString(),
    };

    TelemetryClient mockTelemetryClient = new TelemetryClient(mockTelemetryConfig);
    return mockTelemetryClient;
}
[TestMethod]
public void TestWidgetDoSomething()
{            
    //arrange
    TelemetryClient mockTelemetryClient = this.InitializeMockTelemetryChannel();
    MyWidget widget = new MyWidget(mockTelemetryClient);

    //act
    var result = widget.DoSomething();

    //assert
    Assert.IsTrue(result != null);
    Assert.IsTrue(result.IsSuccess);
}