简体   繁体   English

使用接口模拟 Moq 中的通用方法

[英]Mocking generic methods in Moq with interface

I am trying to setup moq for the following generic interface but getting exception我正在尝试为以下通用接口设置最小起订量,但出现异常

 public interface IReadAccess<TEntity>
 {
     Task<IEnumerable<TEntity>> GetAll();
 }

var m = new Mock<IReadAccess<Foo>>(MockBehavior.Strict);

m.Setup(p => p.GetAll()).ReturnsAsync(new List<Foo>());

m.VerifyAll();

Getting bellow exception得到波纹管异常

Moq.MockException
  HResult=0x80131500
  Message=The following setups on mock
    'Mock<EPIC.CrossCutting.Interfaces.DAL.Framework.IReadAccess<EPIC.CrossCutting.DTOs.Data.Announcement.AnnouncementCrosscutDTO>:00000002>' 
  were not matched:
IReadAccess<AnnouncementCrosscutDTO> p => p.GetAll()

  Source=Moq
  StackTrace:
   at Moq.Mock.VerifyAll()
   at EPIC.Tests.Business.Rules.Announcements.AnnouncementPlanning.CrosscutsProgrammaticActivitiesValidationRuleServiceTests.<ExecuteSuccessTest>d__5.MoveNext() 
in D:\dev\main\Tests\EPIC.Tests.Business.Rules\Announcements\AnnouncementPlanning\CrosscutsProgrammaticActivitiesValidationRuleServiceTests.cs:line 108

Your test is failing correctly because you try to verify that GetAll() was called even though you haven't actually called it.您的测试正确失败,因为您尝试验证 GetAll() 是否已被调用,即使您实际上并未调用它。

It'll pass if you call the method in your test or in the code your are testing.如果您在测试或正在测试的代码中调用该方法,它将通过。

[Fact]
public async Task Test1()
{
    var m = new Mock<IReadAccess<Foo>>(MockBehavior.Strict);
    m.Setup(p => p.GetAll()).ReturnsAsync(new List<Foo>());

    var result = await m.Object.GetAll();

    m.VerifyAll();
}

The clue was in your error message: Message=The following setups on mock .... were not matched: IReadAccess p => p.GetAll()线索在您的错误消息中: Message=The following setups on mock .... are not matching: IReadAccess p => p.GetAll()

Thanks Connell , this is working expected but I have simillar method谢谢康奈尔,这是预期的,但我有类似的方法

public interface IReadAccess<TEntity>  
{  
    Task<IEnumerable<TEntity>> GetAll();   
    Task<IEnumerable<TEntity>> Find(FormattableString whereClause, object whereClauseObject);

} 

and trying to setup并尝试设置

var m = new Mock<IReadAccess<Foo>>(MockBehavior.Strict);
m.Setup(x => x.Find($"ID = @ID", new { ID = 5 })).ReturnsAsync(new List<Foo>());
var result = await m.Object.Find($"ID= @ID", new { ID = 5 });
m.VerifyAll();

after made some changes on the existing code , now setup is working fine but getting error on actual service when it is calling for from test, updated code在对现有代码进行一些更改后,现在设置工作正常,但在从测试、更新代码中调用实际服务时出现错误

var test = new Test {ID = 5};
object whereClause = new { ID = test.ID };
            FormattableString formattableString = $"ID = @ID";

            m.Setup(x => x.Find(formattableString, whereClause)).ReturnsAsync(new List<Foo>());

 var ruleServiceOutput = await this.testValidationRuleService.ExecuteAsync(test);

Actual Code实际代码

public async Task<IRuleServiceOutput<bool>> ExecuteAsync(Test test)
        {
            var errors = new List<string>();

            object whereClause = new { ID = test.ID };
            FormattableString formattableString = $"ID = @ID";

            var output = (await m.Find(formattableString, whereClause)).ToArray();

            return new RuleServiceOutput<bool>(output.Errors.IsEmpty(), output.Errors);
        }

'IReadAccess`1.Find(ID = @ID, { ID = 5 }) invocation failed with mock behavior Strict. 'IReadAccess`1.Find(ID = @ID, { ID = 5 }) 调用失败,模拟行为严格。 All invocations on the mock must have a corresponding setup.'模拟上的所有调用都必须具有相应的设置。

After setting MockBehavior.Default everything working expected :)设置 MockBehavior.Default 后一切正常:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM