如何模拟 return 类型是 'async Task<(IList<ModelClass>, PaginationModel)>'?
How to mock which return type is 'async Task<(IList<ModelClass>, PaginationModel)>'?
我的模拟设置如下
public class LicensePathControllerTest
{
private MockRepository mockRepository;
}
public LicensePathControllerTest()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);
this.mockIJobLicensePathService =
this.mockRepository.Create<IJobLicensePathService>();
this.mockLog = this.mockRepository.Create<ILog>();
}
private LicensePathController CreateLicensePathController()
{
return new LicensePathController(
this.mockIJobLicensePathService.Object,this.mockLog.Object);
}
我的方法是
public async Task<IActionResult> GetLicensePath([FromBody] PathSearch pathSearch)
{
var (paths, pagination) = await _pathService.GetJobPathByFilters(pathSearch); //need to mock this line.
return ok(new OkResponse<IList<JobLicensePath>>(licensePaths, pagination.PageNumber, pagination.PageSize, pagination.TotalPages, pagination.TotalCount));
}
我的服务class方法也返回
public async Task<(IList<JobLicensePath>, PaginationModel)> GetJobPathByFilters(PathSearch pathSearch)
{
//...
IEnumerable<JobLicensePath> objJobLicensePath = null;
objJobLicensePath = await _baseRepository.GetAsync<JobLicensePath>(filter: expression, null, null, skip: skipVal, take: take, false);
return (objJobPath.ToList(), new PaginationModel(pageNumber, pageSize, totalCount));
}
我正在尝试模拟以下几个试验,但都没有设置。
第一次尝试
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(It.IsAny<Task(IList<JobLicensePath>, PaginationModel)>()));
The type arguments for method 'Task.FromResult(TResult)'
cannot be inferred from the usage. Try specifying the type arguments
explicitly.
第二次尝试
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(It.IsAny<IList<JobLicensePath>, PaginationModel>()>));
Using the generic method 'It.IsAny()' requires 1 type
arguments
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(It.IsAny<IList<JobLicensePath>>(), It.IsAny<PaginationModel>()));
No overload for method 'FromResult' takes 2 arguments
It.IsAny用于检查方法的参数。
你可以这样模拟它:
// arrange
(IList<JobLicensePath>, PaginationModel) result = (new List<JobLicensePath>(), new PaginationModel());
var mock = new Mock<IPathService>();
mock
.Setup(s => s.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(result));
您应该使用 Moq 的 ReturnsAsync 方法,如下所示。
// arrange
// Create the dummy object or use the existing one if already exists as part of your mock setup.
IList<JobLicensePath> jobLicensePath = new List<JobLicensePath>();
PaginationModel paginationModel = new PaginationModel();
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.ReturnsAsync((jobLicensePath, paginationModel));
It
class 的方法,如 Is
或 IsAny
,只能在 Setup
方法内部使用。
它们帮助您指定您的模拟应该何时“触发”。
如果您的方法 returns 带有 Task
那么您有多种选择
ReturnAsync
var expectedJobLicensePaths = ...;
var expectedPaginationModel = ...;
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.ReturnsAsync((expectedJobLicensePaths, expectedPaginationModel));
Result
+ Return
从 4.16 开始,您可以 rewrite the above setup to this
var expectedJobLicensePaths = ...;
var expectedPaginationModel = ...;
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()).Result)
.Returns((expectedJobLicensePaths, expectedPaginationModel));
我的模拟设置如下
public class LicensePathControllerTest
{
private MockRepository mockRepository;
}
public LicensePathControllerTest()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);
this.mockIJobLicensePathService =
this.mockRepository.Create<IJobLicensePathService>();
this.mockLog = this.mockRepository.Create<ILog>();
}
private LicensePathController CreateLicensePathController()
{
return new LicensePathController(
this.mockIJobLicensePathService.Object,this.mockLog.Object);
}
我的方法是
public async Task<IActionResult> GetLicensePath([FromBody] PathSearch pathSearch)
{
var (paths, pagination) = await _pathService.GetJobPathByFilters(pathSearch); //need to mock this line.
return ok(new OkResponse<IList<JobLicensePath>>(licensePaths, pagination.PageNumber, pagination.PageSize, pagination.TotalPages, pagination.TotalCount));
}
我的服务class方法也返回
public async Task<(IList<JobLicensePath>, PaginationModel)> GetJobPathByFilters(PathSearch pathSearch)
{
//...
IEnumerable<JobLicensePath> objJobLicensePath = null;
objJobLicensePath = await _baseRepository.GetAsync<JobLicensePath>(filter: expression, null, null, skip: skipVal, take: take, false);
return (objJobPath.ToList(), new PaginationModel(pageNumber, pageSize, totalCount));
}
我正在尝试模拟以下几个试验,但都没有设置。
第一次尝试
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(It.IsAny<Task(IList<JobLicensePath>, PaginationModel)>()));
The type arguments for method 'Task.FromResult(TResult)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
第二次尝试
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(It.IsAny<IList<JobLicensePath>, PaginationModel>()>));
Using the generic method 'It.IsAny()' requires 1 type arguments
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(It.IsAny<IList<JobLicensePath>>(), It.IsAny<PaginationModel>()));
No overload for method 'FromResult' takes 2 arguments
It.IsAny用于检查方法的参数。 你可以这样模拟它:
// arrange
(IList<JobLicensePath>, PaginationModel) result = (new List<JobLicensePath>(), new PaginationModel());
var mock = new Mock<IPathService>();
mock
.Setup(s => s.GetJobPathByFilters(It.IsAny<PathSearch>()))
.Returns(Task.FromResult(result));
您应该使用 Moq 的 ReturnsAsync 方法,如下所示。
// arrange
// Create the dummy object or use the existing one if already exists as part of your mock setup.
IList<JobLicensePath> jobLicensePath = new List<JobLicensePath>();
PaginationModel paginationModel = new PaginationModel();
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.ReturnsAsync((jobLicensePath, paginationModel));
It
class 的方法,如 Is
或 IsAny
,只能在 Setup
方法内部使用。
它们帮助您指定您的模拟应该何时“触发”。
如果您的方法 returns 带有 Task
那么您有多种选择
ReturnAsync
var expectedJobLicensePaths = ...;
var expectedPaginationModel = ...;
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()))
.ReturnsAsync((expectedJobLicensePaths, expectedPaginationModel));
Result
+ Return
从 4.16 开始,您可以 rewrite the above setup to this
var expectedJobLicensePaths = ...;
var expectedPaginationModel = ...;
mockIJobLicensePathService
.Setup(x => x.GetJobPathByFilters(It.IsAny<PathSearch>()).Result)
.Returns((expectedJobLicensePaths, expectedPaginationModel));