Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.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# 如何使Moq理解类型约束对于已验证的调用是可接受的?_C#_Unit Testing_Generics_Moq - Fatal编程技术网

C# 如何使Moq理解类型约束对于已验证的调用是可接受的?

C# 如何使Moq理解类型约束对于已验证的调用是可接受的?,c#,unit-testing,generics,moq,C#,Unit Testing,Generics,Moq,摘要 我目前正在编写一些集成代码,以便与会计系统进行交互 讨论中的会计系统是Acceo Acomba,它使用的SDK变成了分布式COM对象 我已经编写了一个泛型类,用于为任何给定的Acomba实体提供泛型存储库 public abstract class AcombaRepository<TEntity, TNativeRepository> where TEntity : class where TNativeRepository : IBaseDataKey {

摘要

我目前正在编写一些集成代码,以便与会计系统进行交互

讨论中的会计系统是Acceo Acomba,它使用的SDK变成了分布式COM对象

我已经编写了一个泛型类,用于为任何给定的Acomba实体提供泛型存储库

public abstract class AcombaRepository<TEntity, TNativeRepository>
    where TEntity : class
    where TNativeRepository : IBaseDataKey {
    public AcombaRepository( TNativeRepository nativeRepository, IMapper entityMapper ) {
        // Guard clauses...
        NativeRepository = nativeRepository;
        this.entityMapper = entityMapper;
    }

    protected readonly TNativeRepository NativeRepository;

    public TEntity Create( TEntity toCreate ) {
        NativeRepository.ReserveCardNumber(); // Insert
        entityMapper.Map( toCreate, NativeRepository ); // Assigning props 
        NativeRepository.AddCard(); // Save or commit to Acomba
    }
}
公共抽象类存储库
地点:班级
假设地点:Ibakey{
公共Acomba存储库(TNativeRepository nativeRepository,IMapper entityMapper){
//保护条款。。。
NativeRepository=NativeRepository;
this.entityMapper=entityMapper;
}
受保护的只读存储本地存储;
公共触角创建(触角创建){
NativeRepository.ReserveCardNumber();//插入
entityMapper.Map(toCreate,NativeRepository);//分配道具
NativeRepository.AddCard();//保存或提交到Acomba
}
}
iBakey

此接口是系统中任何给定可访问实体的基本实体。为了确保我能够访问它的基础知识,我在我的泛型存储库中设置了这个类型约束

AcombaProductsRepository

这是实际使用基本方法的测试代码

public class AcombaProductsRepository : AcombaRepository<MyProduct, IProduct022> {
    public AcombaPRoductsRepository( IProduct022 nativeRepository, IMapper productMapper ) 
        : base( nativeRepository, productMapper ) { 
    }
}
公共类ACOMBAProducts存储库:AcombaRepository{
公共AcombaPRoductsRepository(IPProduct022 nativeRepository,IMapper productMapper)
:base(nativeRepository,productMapper){
}
}
单元测试

为了确保我的代码充分使用Acomba SDK在Acomba底层数据存储中创建新实体,我验证了某些步骤是否得到严格遵守

public class AcombaProductsRepositoryTests {
    private readonly Mock<IProduct022> nativeRepositoryMock;
    private readonly AcombaProductsRepsoitory sut;

    public AcombaProductsRepositoryTests() {
        nativeRepositoryMock = new Mock<IProduct022>();
        sut = new AcombaProductsRepository( nativeRepositoryMock.Object );
    }

    [Fact]
    public void Create_Should_Reserve_A_Card_Number() {
        var toCreate = new MyProduct();
        nativeRepositoryMock.Setup( r => r.ReserveCardNumber() ).Verifiable();

        sut.Create( toCreate );

        nativeRepositoryMock.Verify( r => r.ReserveCardNumber() );
    }
}
公共类AcombaProductsRepositoryTests{
私有只读Mock nativeRepositoryMock;
私有只读ACOMBAProductsRepository sut;
公共AcombaProductsRepositoryTests(){
nativeRepositoryMock=新Mock();
sut=新AcombaProductsRepository(nativeRepositoryMock.Object);
}
[事实]
公共作废创建\应\保留\卡号(){
var toCreate=new MyProduct();
nativeRepositoryMock.Setup(r=>r.ReserveCardNumber()).Verifiable();
sut.Create(创建);
验证(r=>r.ReserveCardNumber());
}
}
在这里,尽管接口
IProduct022
源自
iBasTakey
,但Moq声明预期调用

  • IPProduct022.保留卡号
从来没有表演过。此外,它还声明执行的调用是

  • iBakey.ReserveCardNumber
就单元测试本身的本质而言,只要调用了
ReserveCardNumber
,实际上执行的调用是否也执行并不重要

如何通过此测试?


更多详细信息(编辑)

下面是来自测试结果的错误消息。


据我所知,Moq执行基本
iBakey
类的调用,而不是
IProduct022
派生类的调用,因为类型约束,我怀疑。

下面的最小示例是基于提供的OP使用的

public class AcombaProductsRepository : AcombaRepository<MyProduct, IProduct022> {
    public AcombaProductsRepository(IProduct022 nativeRepository)
        : base(nativeRepository) {
    }
}

public abstract class AcombaRepository<TEntity, TNativeRepository>
    where TEntity : class
    where TNativeRepository : IBaseDataKey {

    public AcombaRepository(TNativeRepository nativeRepository) {
        NativeRepository = nativeRepository;
    }

    protected readonly TNativeRepository NativeRepository;

    public TEntity Create(TEntity toCreate) {
        NativeRepository.ReserveCardNumber(); // Insert
        NativeRepository.AddCard(); // Save or commit to Acomba
        return toCreate;
    }
}
以下测试基于OP中提供的信息,并使用MSTest和最新版本的Moq进行

[TestClass]
public class AcombaProductsRepositoryTests {
    private readonly Mock<IProduct022> nativeRepositoryMock;
    private readonly AcombaProductsRepository sut;

    public AcombaProductsRepositoryTests() {
        nativeRepositoryMock = new Mock<IProduct022>();
        sut = new AcombaProductsRepository(nativeRepositoryMock.Object);
    }

    [TestMethod]
    public void _Create_Should_Reserve_A_Card_Number() {
        //Arrange
        var toCreate = new MyProduct();
        nativeRepositoryMock.Setup(r => r.ReserveCardNumber()).Verifiable();

        //Act
        sut.Create(toCreate);

        //Asert
        nativeRepositoryMock.Verify(r => r.ReserveCardNumber());
    }
}
[TestClass]
公共类ACOMBA产品存储测试{
私有只读Mock nativeRepositoryMock;
私有只读ACOMBAProducts存储sut;
公共AcombaProductsRepositoryTests(){
nativeRepositoryMock=新Mock();
sut=新AcombaProductsRepository(nativeRepositoryMock.Object);
}
[测试方法]
公共作废(创建)(应保留)(卡号){
//安排
var toCreate=new MyProduct();
nativeRepositoryMock.Setup(r=>r.ReserveCardNumber()).Verifiable();
//表演
sut.Create(创建);
//阿塞特
验证(r=>r.ReserveCardNumber());
}
}
练习时的测试毫无例外地通过了


我建议对原始代码进行审查,因为目前提出的问题是不可复制的

提供一个可用于重现问题的。目前没有足够的详细信息,因此如果
nativeepositorymock.Setup()
已经是
.Verifiable()
,那么在断言过程中需要做的就是
nativeepositorymock.Verify()将验证所有可验证的设置。@感谢您的反馈。我知道
.Verify()
这件事,但我想特别验证这个调用,因为我正在进行单元测试。我发现,因为我在整个测试中为不同的方法调用设置了mock,所以我需要检查是否只执行了这个调用。显示测试中的代码,以便可以使用它来重现问题。如果我们不能运行相同的代码并遇到相同的问题,我们就不能提供太多帮助。这样我们就可以找到原因和解决办法。同样需要一个问题,否则这个问题只会脱离主题。@Nkosi在基本存储库和派生存储库中编辑了测试中的代码,以访问产品实体。
[TestClass]
public class AcombaProductsRepositoryTests {
    private readonly Mock<IProduct022> nativeRepositoryMock;
    private readonly AcombaProductsRepository sut;

    public AcombaProductsRepositoryTests() {
        nativeRepositoryMock = new Mock<IProduct022>();
        sut = new AcombaProductsRepository(nativeRepositoryMock.Object);
    }

    [TestMethod]
    public void _Create_Should_Reserve_A_Card_Number() {
        //Arrange
        var toCreate = new MyProduct();
        nativeRepositoryMock.Setup(r => r.ReserveCardNumber()).Verifiable();

        //Act
        sut.Create(toCreate);

        //Asert
        nativeRepositoryMock.Verify(r => r.ReserveCardNumber());
    }
}