在C#中伪造泛型方法调用不会返回带有FakeiTasy的正确对象
我有这个方法需要测试在C#中伪造泛型方法调用不会返回带有FakeiTasy的正确对象,c#,unit-testing,fakeiteasy,C#,Unit Testing,Fakeiteasy,我有这个方法需要测试 public async Task<IActionResult> Completed(string nprUserId, [FromBody] DateRangeDto model) { var result = await _geAppService.Completed<ExpandoObject>(nprUserId, model.StartDate, model.EndDate); var r =
public async Task<IActionResult> Completed(string nprUserId, [FromBody] DateRangeDto model)
{
var result = await _geAppService.Completed<ExpandoObject>(nprUserId, model.StartDate, model.EndDate);
var r = result as OperationResult;
if (r == null)
{
// There is no error. Return JSON
return Json(result, camelCaseOption);
}
else
{
// An error occurred. Return a 404 and include the error message
return NotFound(r.ErrorMessage);
}
}
公共异步任务已完成(字符串nprUserId,[FromBody]DateRangeDto model)
{
var result=wait _geAppService.Completed(nprUserId、model.StartDate、model.EndDate);
var r=作为操作结果的结果;
if(r==null)
{
//没有错误。返回JSON
返回Json(结果,选项);
}
其他的
{
//发生错误。返回404并包含错误消息
返回NotFound(r.ErrorMessage);
}
}
这是我的测试
[Fact]
[Trait("Controller", "Completed")]
public async Task Completed_WhenRIsNotNull_ReturnNotFoundWithMessage()
{
//arrange
string nprUserId = string.Empty;
var model = CreateRandomDateRangeDto();
OperationResult r = CreateRandomOperationResult();
var startDate = DateTime.Now;
var endDate = DateTime.Now;
//I tried this
A.CallTo(nprAppService)
.Where(call => call.Method.Name == "Completed")
.WithReturnType<OperationResult>()
.Returns(r);
//I tried this as well
A.CallTo(() => nprAppService.Completed<ExpandoObject>(nprUserId, startDate, endDate))
.Returns(r);
//act
var result = await controller.Completed(nprUserId, model);
// Assert
A.CallTo(() => nprAppService.Completed<ExpandoObject>(nprUserId, startDate, endDate))
.MustHaveHappened();
result.Should().BeOfType<NotFoundObjectResult>()
.Subject.Value.Should().BeOfType<string>();
}
[事实]
[特征(“控制者”、“完成”)]
公共异步任务已完成\u当nRnotNull\u ReturnNotFoundWithMessage()时
{
//安排
string nprouserid=string.Empty;
var model=CreateRandomDateRangeDto();
OperationResult r=CreateRandomOperationResult();
var startDate=DateTime.Now;
var endDate=DateTime.Now;
//我试过这个
A.CallTo(nprAppService)
.Where(call=>call.Method.Name==“已完成”)
.WithReturnType()
.报税表(r);
//我也试过这个
A.CallTo(()=>nprapservice.Completed(nprUserId、startDate、endDate))
.报税表(r);
//表演
var result=await controller.Completed(用户ID,模型);
//断言
A.CallTo(()=>nprapservice.Completed(nprUserId、startDate、endDate))
.一定发生过();
result.Should().BeOfType()
.Subject.Value.Should().BeOfType();
}
调用sut:控制器时,完整的泛型方法将返回一个对象,而不是OperationResult
如何解决此问题?假设
CreateRandomDateRangeDto
返回StartDate
和EndDate
设置为DateTime的模型。现在
您的测试应该使用model.StartDate
和model.EndDate
而不是测试方法中的StartDate
和EndDate
。因为他们的价值观是不同的
[Fact]
[Trait("Controller", "Completed")]
public async Task Completed_WhenRIsNotNull_ReturnNotFoundWithMessage()
{
//arrange
string nprUserId = string.Empty;
var model = CreateRandomDateRangeDto();
OperationResult r = CreateRandomOperationResult();
A.CallTo(() => nprAppService.Completed<ExpandoObject>(nprUserId, model.StartDate, model.EndDate))
.Returns(r);
//act
var result = await controller.Completed(nprUserId, model);
// Assert
A.CallTo(() => nprAppService.Completed<ExpandoObject>(nprUserId, model.StartDate, model.EndDate))
.MustHaveHappened();
result.Should().BeOfType<NotFoundObjectResult>()
.Subject.Value.Should().BeOfType<string>();
}
第二种方法需要精确的值/对象才能返回指定的对象。这就是为什么测试只对model.EndDate
和model.StartDate
如果您不关心开始日期和结束日期值的匹配,您可以
A.CallTo(()=>nprapservice.Completed(nprUserId,A.。。。。。。。。。。)
.报税表(r);
假设CreateRandomDateRangeDto
返回StartDate
和EndDate
设置为DateTime的模型。现在
您的测试应该使用model.StartDate
和model.EndDate
而不是测试方法中的StartDate
和EndDate
。因为他们的价值观是不同的
[Fact]
[Trait("Controller", "Completed")]
public async Task Completed_WhenRIsNotNull_ReturnNotFoundWithMessage()
{
//arrange
string nprUserId = string.Empty;
var model = CreateRandomDateRangeDto();
OperationResult r = CreateRandomOperationResult();
A.CallTo(() => nprAppService.Completed<ExpandoObject>(nprUserId, model.StartDate, model.EndDate))
.Returns(r);
//act
var result = await controller.Completed(nprUserId, model);
// Assert
A.CallTo(() => nprAppService.Completed<ExpandoObject>(nprUserId, model.StartDate, model.EndDate))
.MustHaveHappened();
result.Should().BeOfType<NotFoundObjectResult>()
.Subject.Value.Should().BeOfType<string>();
}
第二种方法需要精确的值/对象才能返回指定的对象。这就是为什么测试只对model.EndDate
和model.StartDate
如果您不关心开始日期和结束日期值的匹配,您可以
A.CallTo(()=>nprapservice.Completed(nprUserId,A.。。。。。。。。。。)
.报税表(r);
您的方法不起作用的原因:第一种方法:我们没有看到nprAppService.Completed
的定义,但基于r=result as OperationResult
,我猜它不会返回OperationResult
。因此,WithReturnType的会导致您的呼叫配置不匹配。我想如果你用NonovoidReturnType将其切换到,你会成功的。第二种方法:正如@Chekkan所说,您将fake配置为只响应特定的日期参数,因此当提供其他参数时,FakeItEasy应用其默认行为。您的方法不起作用的原因:第一种方法:我们没有看到nprapservice.Completed的定义,但是基于r=result as OperationResult
,我猜它不会返回OperationResult
。因此,WithReturnType的会导致您的呼叫配置不匹配。我想如果你用NonovoidReturnType将其切换到,你会成功的。第二种方法:正如@Chekkan所说,您将fake配置为只响应特定的日期参数,因此当提供其他参数时,FakeItEasy应用了其默认行为。为什么传递的值在这种情况下很重要?希望通过更新添加更多解释,使事情更清楚。为什么传递的值在这种情况下很重要?添加了更多的解释,并进行了更新,希望能使事情更清楚。