Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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#.net标准)_C#_Unit Testing_Testing_Moq_Code Coverage - Fatal编程技术网

代码覆盖率未选取测试(c#.net标准)

代码覆盖率未选取测试(c#.net标准),c#,unit-testing,testing,moq,code-coverage,C#,Unit Testing,Testing,Moq,Code Coverage,我已经实现了我自己的记录器,它遵循ILogger接口。在内部,它有AppInsights客户端,这就是我的日志记录器实际记录的内容。这是我的课程的简化版本: public class AppInsightsLogger : ILogger { internal TelemetryClient Client { get; set; } public AppInsightsLogger(string instrumentationKey) { Telemet

我已经实现了我自己的记录器,它遵循ILogger接口。在内部,它有AppInsights客户端,这就是我的日志记录器实际记录的内容。这是我的课程的简化版本:

public class AppInsightsLogger : ILogger
{
    internal TelemetryClient Client { get; set; }

    public AppInsightsLogger(string instrumentationKey)
    {
        TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
        Client = new TelemetryClient();
    }

    public void Log<T>(LogLevel logLevel, EventId eventId, T state, Exception exception,
        Func<T, Exception, string> formatter)
    {
        if (string.IsNullOrEmpty(eventId.Name))
        {
            StackFrame frame = new StackFrame(1); 
            var method = frame.GetMethod();
            var type = method.DeclaringType;
            var name = method.Name;

            eventId = new EventId(eventId.Id == 0 ? BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0) : eventId.Id, $"{type}:{name}");
        }

        var props = new Dictionary<string, string>
        {
            { "EventId", eventId.Id.ToString() },
            { "EventName", eventId.Name }
        };

        var telemetry = new EventTelemetry(eventId.Name);

        if (!string.IsNullOrEmpty(state.ToString()))
        {
            telemetry.Properties.Add("SummaryMessage", state.ToString());
        }

        foreach (var property in props)
        {
            telemetry.Properties.Add(property);
        }

        Client.TrackEvent(telemetry);
    }
}
但是当我运行这个测试时(通过得很好),我的代码覆盖率监视器(Jetbrain的dotCoverage)并没有覆盖它

你知道我如何正确地执行这个测试,从而正确地覆盖代码吗?我也在使用最小起订量

问题是因为它是一个模拟实例吗?我不能嘲笑TelemetryClient,因为我的另一个想法是测试AppInsightsLogger的实例,然后验证TelemetryClient.log是否被调用,但它是一个密封类,使测试复杂化:-/

提前感谢您提供的任何提示!!
注意:我对编写测试相当陌生-我理解这些概念,但没有实际执行。

好吧,您的代码没有被涵盖,因为它没有被执行。您设置了一个模拟对象,然后在此设置上调用了一个方法。而不是你的真正的代码,moq踢进来,只是返回你设置的值

所以当你打电话时:

mock.Object.Log(LogLevel.Information, new EventId(1, "test"), "test", null, null);
它不会进入代码,它会在模拟对象上查找匹配的设置,并找到一个:

mock.Setup(m => 
             m.Log<string>(It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<string>(), null, null));
将其注入构造函数或属性中的记录器(使用DI):

最后在你的测试中:

var telemetryMock = new Mock<ITelemetryClientWrapper>();
var target = new MyLogger(telemetryMock.Object);
target.Log(...);

telemetryMock.Verify(c => c.TrackEvent());
var telemetryMock=new Mock();
var target=新的MyLogger(遥测模拟对象);
target.Log(…);
telemetryMock.Verify(c=>c.TrackEvent());

简而言之:您不模拟您测试的类,而是模拟该类的依赖关系。这样,当您测试类时,来自其他类的代码不会运行,也不会影响您的测试结果。

好吧,您的代码没有被覆盖,因为它没有被执行。您设置了一个模拟对象,然后在此设置上调用了一个方法。而不是你的真正的代码,moq踢进来,只是返回你设置的值

所以当你打电话时:

mock.Object.Log(LogLevel.Information, new EventId(1, "test"), "test", null, null);
它不会进入代码,它会在模拟对象上查找匹配的设置,并找到一个:

mock.Setup(m => 
             m.Log<string>(It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<string>(), null, null));
将其注入构造函数或属性中的记录器(使用DI):

最后在你的测试中:

var telemetryMock = new Mock<ITelemetryClientWrapper>();
var target = new MyLogger(telemetryMock.Object);
target.Log(...);

telemetryMock.Verify(c => c.TrackEvent());
var telemetryMock=new Mock();
var target=新的MyLogger(遥测模拟对象);
target.Log(…);
telemetryMock.Verify(c=>c.TrackEvent());

简而言之:您不模拟您测试的类,而是模拟该类的依赖关系。因此,当您测试类时,来自其他类的代码不会运行,也不会影响您的测试结果。

代码覆盖率监视器是正确的:您在模拟您正在测试的类,而实际实现永远不会运行。与其模拟
ILogger
,不如在
AppInsightsLogger
的真实实例上调用Log方法,并模拟
TelemetryClient
。TelemetryClient是一个密封类,但:(但这是有意义的,因为它是模拟实例-不确定如何测试它将遥测客户端封装/包装在您控制的抽象后面,并将其注入记录器中。记录器与实现问题紧密耦合,这使得很难单独进行单元测试。代码覆盖率监视器是正确的:您是检查您正在测试的类,而实际实现从未运行过。您要做的不是模拟
ILogger
,而是在
AppInsightsLogger
的真实实例上调用Log方法,并模拟
TelemetryClient
。TelemetryClient是一个密封的类,但:(但这是有意义的,因为它是模拟实例-不确定如何测试它将遥测客户端封装/包装在您控制的抽象后面,并将其注入记录器中。记录器与实现问题紧密耦合,这使得很难单独进行单元测试。