我遇到了以下情况,我正在考虑测试我的服务的正确方法.我有2个服务和2个存储库.

public class ServiceB : IServiceB
{
    public ServiceA(IRepoB)
    {
        
    }
    
    public async Task AuditInsert(param, param)
    {
        IRepoB.Insert(param, param)
    }
}


public class ServiceA : IServiceA
{
    public ServiceA(IRepoA, IServiceB)
    {
        
    }
    
    public async bool DoSomething(param)
    {
        //logic here
        
        IRepoA.Merge(param)
        IServiceB.AuditInsert(param, param)
    }
}


////// Testing part
public class ServiceATests
{
    private readonly ServiceA _sut;
    
    private readonly Mock<IRepoA> _repoA = new(MockBehavior.Strict)
    private readonly Mock<ServiceB> _serviceB = new(MockBehavior.Strict)
    
    _repoA.Setup(x => x.Merge(It.IsAny<ParamEntity>)).Return(Task.TaskCompleted)
    _serviceB.Setup(x => x.AuditInsert(It.IsAny<ParamEntity>, It.IsAny<ParamEntity>)).Return(Task.TaskCompleted)
    
    _sut = new ServiceA(_repoA.Object, _serviceB.Object)    
}

[Fact]
public async Task TestSomething()
{
    //arrange
    var testParam = {} // an object
    //act
    await _sut.DoSomething(testParam)
    
    //assert
    _repoA.Verify(x => x.Merge(), Times.Once)
    
    _serviceB.Verify(x => x.AuditInsert(It.IsAny<ParamEntity>, It.IsAny<ParamEntity>), Times.Once)  
}

我在行为中遇到的错误是"调用失败,模拟行为严格,模拟上的所有调用都必须有相应的设置".

代码在IServiceB.AuditExec(param,param)行上的ServicA中失败.

可能是因为当我设置ServicB时,我应该以某种方式通过RepoB的模拟?但我不知道如何做到这一点. 或者,如果我删除_serviceB.Verify部分并仅创建一个新类来仅测试serviceB,那会更好?

测试部分应该如何解决这个依赖链?

我正在将xUnit与Mock一起使用

我创建了一个带有一个项目的小型git repo,其中的错误可以复制https://github.com/masterxfile/xUnitExample/tree/main/WebApplication1

推荐答案

提供的复制会导致以下错误:

IAuditService.InsertAudit("测试","是")调用失败,模拟行为Strict. 调用需要返回一个值,因此必须有提供该值的相应设置.

.Returns(Task.CompletedTask)添加到相应的模拟可以解决这个问题:

auditService.Setup(x => x.InsertAudit("test", "Yes"))
    .Returns(Task.CompletedTask);

Csharp相关问答推荐

GC未修复有关.Net Entity框架版本8(C#控制台应用程序.Net8.02)的内存泄漏

我们应该如何在IHostedService中使用按请求的GbContent实例?

更改对象的旋转方向

EF Core 8—应用客户端投影后无法转换集操作

编写DataAnnotations自定义验证器的多种方法

使用LayoutKind在C#中嵌套 struct .显式

如何测量在使用UTF8而不是C#中的UTF16编码字符串时内存使用量的增长

如何从ASP.NET核心MVC视图和Blazor传递数据

C#使用TextFieldParser读取.csv,但无法使用";0";替换创建的列表空条目

使用Dapper映射联接查询对象数据到使用SplitOn;

如何比较C#中的L和ł(波兰字符)返回TRUE

正确处理嵌套的本机集合

如何在GRPC代码First服务的返回类型上使用多态性?

如何从Entity Framework Core中填充ListIInterface

System.NotSupportdException:流不支持读取

JSON串行化程序问题.SQLite中的空值

如何在单击按钮后多次异步更新标签

如何从原始图像到新创建的图像获得相同的特定 colored颜色 ,并且具有相同的 colored颜色 量和相同的宽度和高度?

在C#中通过Matheval使用自定义公式

如何将行添加到DataGrid以立即显示它?