C# 单元测试不显示异步/等待的代码覆盖率
我使用的是vs2017,没有一个单元测试显示代码覆盖率。我正在使用async/await和MOQC# 单元测试不显示异步/等待的代码覆盖率,c#,unit-testing,asynchronous,moq,C#,Unit Testing,Asynchronous,Moq,我使用的是vs2017,没有一个单元测试显示代码覆盖率。我正在使用async/await和MOQ [TestMethod] [TestCategory("SeriesRepository")] public void GetSeriesAsyncShouldReturnSeriesId12345() { var repositoryMock = new Mock<ISeriesRepository>(); var seriesId = "12345"; va
[TestMethod]
[TestCategory("SeriesRepository")]
public void GetSeriesAsyncShouldReturnSeriesId12345()
{
var repositoryMock = new Mock<ISeriesRepository>();
var seriesId = "12345";
var channel = 75864;
var mockSeries = new Mock<ISeries>();
mockSeries.SetupGet(x => x.SeriesId).Returns("12345");
repositoryMock
.Setup(x => x.GetSeriesAsync(seriesId, channel))
.ReturnsAsync(mockSeries.Object);
var result = repositoryMock.Object.GetSeriesAsync(seriesId, channel).Result;
result.SeriesId.Should().Be(seriesId);
}
[TestMethod]
[测试类别(“系列报告”)]
public void GetSeriesAsynchshouldReturnSeriesID12345()
{
var repositoryMock=new Mock();
var seriesId=“12345”;
var通道=75864;
var mockSeries=new Mock();
SetupGet(x=>x.SeriesId).Returns(“12345”);
重置模拟
.Setup(x=>x.GetSeriesAsync(seriesId,通道))
.ReturnsAsync(mockSeries.Object);
var result=repositoryMock.Object.GetSeriesAsync(seriesId,channel.result);
result.SeriesId.Should().Be(SeriesId);
}
无需等待repositoryMock安装完成。因此,您的测试用例将在异步调用完成之前结束
通过添加以下内容确保您等待:
repositryMock.setup(...).ReturnsAsync(...).GetAwaiter().GetResult();
或
或
这应该可以解决您的问题。第一个事实是,您实际上并没有在测试中测试任何东西,因为您只是创建模拟并调用模拟 您只是在测试mocking框架是否如广告所示工作 其次,测试也可以是异步的,以允许测试按顺序进行
[TestMethod]
[TestCategory("SeriesRepository")]
public async Task GetSeriesAsyncShouldReturnSeriesId12345() {
var repositoryMock = new Mock<ISeriesRepository>();
var seriesId = "12345";
var channel = 75864;
var mockSeries = new Mock<ISeries>();
mockSeries.Setup(_ => _.SeriesId).Returns(seriesId);
repositoryMock
.Setup(_ => _.GetSeriesAsync(seriesId, channel))
.ReturnsAsync(mockSeries.Object);
var result = await repositoryMock.Object.GetSeriesAsync(seriesId, channel);
result.SeriesId.Should().Be(seriesId);
}
[TestMethod]
[测试类别(“系列报告”)]
公共异步任务GetSeriesAsyncShouldReturnSeriesId12345(){
var repositoryMock=new Mock();
var seriesId=“12345”;
var通道=75864;
var mockSeries=new Mock();
mockSeries.Setup(=>u.SeriesId).Returns(SeriesId);
重置模拟
.Setup(=>u.GetSeriesAsync(seriesId,通道))
.ReturnsAsync(mockSeries.Object);
var result=await repositoryMock.Object.GetSeriesAsync(seriesId,channel);
result.SeriesId.Should().Be(SeriesId);
}
假设发生的情况是,为了验证某些所需的行为,您模拟了被测试目标的依赖项,使其行为符合预期
假设我们想测试一个类的目标方法
public class SeriesService {
private readonly ISeriesRepository repository;
public SeriesService(ISeriesRepository repository
this.repository = repository;
}
public async Task<ISeries> GetSeries(string seriesId, int channel) {
var series = await repository.GetSeriesAsync(seriesId, channel);
//...do some other stuff
return series;
}
}
公共类服务{
私有只读存储库;
公共服务(iSeries)存储库
this.repository=存储库;
}
公共异步任务GetSeries(字符串序列ID,int通道){
var series=await repository.GetSeriesAsync(seriesId,channel);
//…做些别的事
返回序列;
}
}
然后,一个示例测试将如下所示
[TestMethod]
[TestCategory("SeriesRepository")]
public async Task TargetMethodShouldReturnSeriesId12345() {
//Assert
var repositoryMock = new Mock<ISeriesRepository>();
var seriesId = "12345";
var channel = 75864;
var mockSeries = new Mock<ISeries>();
mockSeries.Setup(_ => _.SeriesId).Returns(seriesId);
repositoryMock
.Setup(_ => _.GetSeriesAsync(seriesId, channel))
.ReturnsAsync(mockSeries.Object);
var target = new SeriesService(repositoryMock.Object);
//Act
var result = await target.GetSeries(seriesId, channel);
//Assert
result.Should().NotBeNull();
result.SeriesId.Should().Be(seriesId);
}
[TestMethod]
[测试类别(“系列报告”)]
公共异步任务targetMethod应返回Seriesid12345(){
//断言
var repositoryMock=new Mock();
var seriesId=“12345”;
var通道=75864;
var mockSeries=new Mock();
mockSeries.Setup(=>u.SeriesId).Returns(SeriesId);
重置模拟
.Setup(=>u.GetSeriesAsync(seriesId,通道))
.ReturnsAsync(mockSeries.Object);
var target=newserieservice(repositoryMock.Object);
//表演
var result=await target.GetSeries(seriesId,channel);
//断言
result.Should().NotBeNull();
result.SeriesId.Should().Be(SeriesId);
}
您似乎只是在调用模拟方法,这不会导致调用任何非测试代码。您希望此测试包含哪些未显示为已覆盖的代码?您是否在问为什么单元测试代码未显示为已覆盖,或者为什么实际逻辑代码未显示为已覆盖?如果是前者,请确保您的测试s实际运行。如果是后者,您在哪里调用实际逻辑代码?似乎您正在设置模拟,然后确保模拟按模拟的方式运行。您要在此处测试的实际逻辑代码是什么?您的意思是,除了读取.Result
这是一个阻塞调用之外?(如果确实涉及任何任务,则应为阻塞调用)。是的,我们应该进行此阻塞调用;以确保在下一次调用发生之前执行所有涉及的任务。如果您的测试方法是异步的,那么您可以等待它而不是阻塞调用。我对TargetClass的类型感到困惑。TargetClass与我的SeriesService类类似。我的SeriesService类需要ISeriesRepository待注入。@user3582849可能是正确的。显示该类的示例,以便我们可以为其制定一个独立的单元测试。谢谢。完成了。这算是存储库测试还是服务测试?我创建了一个名为SeriesRepositoryTest的测试类,如果这是测试Repository,我应该如何测试服务ice layer?@user3582849此单元测试在隔离状态下测试SerieService
。本例中的存储库是一个显式的依赖项,它被模拟,以便允许在隔离状态下测试被测系统,而不必使用实际的存储库实现。这是针对web api的,我还有一个控制器。Wh至少,您建议用这个进行单元测试吗?编写一个测试控制器的单元测试是否有意义?iSeries服务被注入到控制器中。
public class SeriesService {
private readonly ISeriesRepository repository;
public SeriesService(ISeriesRepository repository
this.repository = repository;
}
public async Task<ISeries> GetSeries(string seriesId, int channel) {
var series = await repository.GetSeriesAsync(seriesId, channel);
//...do some other stuff
return series;
}
}
[TestMethod]
[TestCategory("SeriesRepository")]
public async Task TargetMethodShouldReturnSeriesId12345() {
//Assert
var repositoryMock = new Mock<ISeriesRepository>();
var seriesId = "12345";
var channel = 75864;
var mockSeries = new Mock<ISeries>();
mockSeries.Setup(_ => _.SeriesId).Returns(seriesId);
repositoryMock
.Setup(_ => _.GetSeriesAsync(seriesId, channel))
.ReturnsAsync(mockSeries.Object);
var target = new SeriesService(repositoryMock.Object);
//Act
var result = await target.GetSeries(seriesId, channel);
//Assert
result.Should().NotBeNull();
result.SeriesId.Should().Be(seriesId);
}