簡體   English   中英

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

[英]Mocking generic methods in Moq with interface

我正在嘗試為以下通用接口設置最小起訂量,但出現異常

 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();

得到波紋管異常

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

您的測試正確失敗,因為您嘗試驗證 GetAll() 是否已被調用,即使您實際上並未調用它。

如果您在測試或正在測試的代碼中調用該方法,它將通過。

[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();
}

線索在您的錯誤消息中: Message=The following setups on mock .... are not matching: IReadAccess p => p.GetAll()

謝謝康奈爾,這是預期的,但我有類似的方法

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

} 

並嘗試設置

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();

在對現有代碼進行一些更改后,現在設置工作正常,但在從測試、更新代碼中調用實際服務時出現錯誤

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);

實際代碼

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 }) 調用失敗,模擬行為嚴格。 模擬上的所有調用都必須具有相應的設置。

設置 MockBehavior.Default 后一切正常:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM