kub*_*wlo 0 c# moq xunit asp.net-core
我正在为我的控制器中的用户创建方法编写单元测试。当我运行单元测试时,它return ValidationProblem();在我的控制器方法的行中返回 NullReferenceException
。
[xUnit.net 00:00:01.16] WotkTimeManager.Tests.UsersControllerTests.PostUsers_BadResult_WhenInvalidData [FAIL]
X WotkTimeManager.Tests.UsersControllerTests.PostUsers_BadResult_WhenInvalidData [285ms]
Error Message:
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
at Microsoft.AspNetCore.Mvc.ControllerBase.ValidationProblem(String detail, String instance, Nullable`1 statusCode, String title, String type, ModelStateDictionary modelStateDictionary)
at Microsoft.AspNetCore.Mvc.ControllerBase.ValidationProblem(ModelStateDictionary modelStateDictionary)
at Microsoft.AspNetCore.Mvc.ControllerBase.ValidationProblem()
at WorkTimeManager.Controllers.UsersController.Post(UserCreateDto user) in /mnt/c/Users/kubw1/WorkTimeManagerSolution/src/WorkTimeManager/Controllers/UsersController.cs:line 72
at WotkTimeManager.Tests.UsersControllerTests.PostUsers_BadResult_WhenInvalidData() in /mnt/c/Users/kubw1/WorkTimeManagerSolution/test/WotkTimeManager.Tests/UsersControllerTests.cs:line 92
--- End of stack trace from previous location where exception was thrown ---
Run Code Online (Sandbox Code Playgroud)
我的控制器方法
[HttpPost]
public async Task<ActionResult<string>> Post(UserCreateDto user)
{
var userModel = _mapper.Map<User>(user);
var result = await _userManager.CreateAsync(userModel, user.password);
if (result.Succeeded)
{
return Ok();
}
else
{
foreach (var err in result.Errors)
{
ModelState.AddModelError(err.Code, err.Description);
}
return ValidationProblem();
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试
[Fact]
public async Task PostUsers_BadResult_WhenInvalidData()
{
var user = new UserCreateDto
{
username = "test",
password = "testp",
email = "email@wp.pl"
};
userManager
.Setup(x => x.CreateAsync(It.IsAny<User>(), It.IsAny<string>()))
.ReturnsAsync(IdentityResult.Failed(new IdentityError { Code = "Problem", Description = "Not working" })).Verifiable();
controller = new UsersController(new UnitOfWork(dbContext), userManager.Object, mapper);
var result = await controller.Post(user);
Assert.IsType<ValidationProblemDetails>(result.Result);
}
Run Code Online (Sandbox Code Playgroud)
查看抛出的方法的来源:
public virtual ActionResult ValidationProblem(
string detail = null,
string instance = null,
int? statusCode = null,
string title = null,
string type = null,
[ActionResultObjectValue] ModelStateDictionary modelStateDictionary = null)
{
modelStateDictionary ??= ModelState;
var validationProblem = ProblemDetailsFactory.CreateValidationProblemDetails(...);
Run Code Online (Sandbox Code Playgroud)
那个好像可以扔。那么ProblemDetailsFactory从何而来呢?
public ProblemDetailsFactory ProblemDetailsFactory
{
get
{
if (_problemDetailsFactory == null)
{
_problemDetailsFactory = HttpContext?.RequestServices?.GetRequiredService<ProblemDetailsFactory>();
}
return _problemDetailsFactory;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_problemDetailsFactory = value;
}
}
Run Code Online (Sandbox Code Playgroud)
你没有HttpContext向你的控制器提供 an (如果你提供了,你没有注册 a ProblemDetailsFactory),所以确实,这个 getter 返回null,导致调用CreateValidationProblemDetails()抛出一个 NRE。
所以你需要提供它。ASP.NET 使用的 DefaultProblemDetailsFactory 是internal,所以你最好模拟它:
controller.ProblemDetailsFactory = new Mock<ProblemDetailsFactory>();
Run Code Online (Sandbox Code Playgroud)
然后设置您期望的呼叫。
| 归档时间: |
|
| 查看次数: |
1254 次 |
| 最近记录: |