c# – .NET CORE测试 – 使用FakeItEasy模拟IHttpContextAccessor
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – .NET CORE测试 – 使用FakeItEasy模拟IHttpContextAccessor,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5580字,纯文字阅读大概需要8分钟。
内容图文
![c# – .NET CORE测试 – 使用FakeItEasy模拟IHttpContextAccessor](/upload/InfoBanner/zyjiaocheng/806/8282e01fddfb479783316ed271d92721.jpg)
我坚持嘲笑IHttpContextAccessor进行一些web api集成测试.我的目标是能够模拟IHttpContextAccessor并返回NameIdentifier声明和RemoteIpAddress.
测试
public class InsertUser : TestBase
{
private UserController _userController;
[OneTimeSetUp]
public void OneTimeSetUp()
{
IStringLocalizer<UserController> localizer = A.Fake<IStringLocalizer<UserController>>();
_userController = new UserController(localizer, Mapper, UserService, StatusService, IdentityService);
_userController.ControllerContext = A.Fake<ControllerContext>();
_userController.ControllerContext.HttpContext = A.Fake<DefaultHttpContext>();
var fakeClaim = A.Fake<Claim>(x => x.WithArgumentsForConstructor(() => new Claim(ClaimTypes.NameIdentifier, "1")));
var fakeIdentity = A.Fake<ClaimsPrincipal>();
A.CallTo(() => fakeIdentity.FindFirst(ClaimTypes.NameIdentifier)).Returns(fakeClaim);
A.CallTo(() => _userController.ControllerContext.HttpContext.User).Returns(fakeIdentity);
StatusTypeEntity statusType = ObjectMother.InsertStatusType(StatusTypeEnum.StatusType.User);
StatusEntity status = ObjectMother.InsertStatus(StatusEnum.Status.Active, statusType);
ObjectMother.InsertUser("FirstName", "LastName", "Email@Email.Email", "PasswordHash", "PasswordSalt", status);
}
public static IEnumerable TestCases
{
get
{
//InsertUser_Should_Insert
yield return new TestCaseData(new InsertUserModel
{
FirstName = "FirstName",
LastName = "LastName",
StatusId = 1,
Email = "Email2@Email.Email"
},
1,
2).SetName("InsertUser_Should_Insert");
//InsertUser_Should_Not_Insert_When_StatusId_Not_Exist
yield return new TestCaseData(new InsertUserModel
{
FirstName = "FirstName",
LastName = "LastName",
StatusId = int.MaxValue,
Email = "Email2@Email.Email"
},
1,
1).SetName("InsertUser_Should_Not_Insert_When_StatusId_Not_Exist");
//InsertUser_Should_Not_Insert_When_Email_Already_Exist
yield return new TestCaseData(new InsertUserModel
{
FirstName = "FirstName",
LastName = "LastName",
StatusId = 1,
Email = "Email@Email.Email"
},
1,
1).SetName("InsertUser_Should_Not_Insert_When_Email_Already_Exist");
}
}
[Test, TestCaseSource(nameof(TestCases))]
public async Task Test(InsertUserModel model, int userCountBefore, int userCountAfter)
{
//Before
int resultBefore = Database.User.Count();
resultBefore.ShouldBe(userCountBefore);
//Delete
await _userController.InsertUser(model);
//After
int resultAfter = Database.User.Count();
resultAfter.ShouldBe(userCountAfter);
}
}
调节器
[Route("api/administration/[controller]")]
[Authorize(Roles = "Administrator")]
public class UserController : Controller
{
private readonly IStringLocalizer<UserController> _localizer;
private readonly IMapper _mapper;
private readonly IUserService _userService;
private readonly IStatusService _statusService;
private readonly IIdentityService _identityService;
public UserController(IStringLocalizer<UserController> localizer,
IMapper mapper,
IUserService userService,
IStatusService statusService,
IIdentityService identityService)
{
_localizer = localizer;
_mapper = mapper;
_userService = userService;
_statusService = statusService;
_identityService = identityService;
}
[HttpPost("InsertUser")]
public async Task<IActionResult> InsertUser([FromBody] InsertUserModel model)
{
if (model == null || !ModelState.IsValid)
{
return Ok(new GenericResultModel(_localizer["An_unexpected_error_has_occurred_Please_try_again"]));
}
StatusModel status = await _statusService.GetStatus(model.StatusId, StatusTypeEnum.StatusType.User);
if (status == null)
{
return Ok(new GenericResultModel(_localizer["Could_not_find_status"]));
}
UserModel userExist = await _userService.GetUser(model.Email);
if (userExist != null)
{
return Ok(new GenericResultModel(_localizer["Email_address_is_already_in_use"]));
}
UserModel user = _mapper.Map<InsertUserModel, UserModel>(model);
var letrTryAndGetUserIdFromNameIdentifier = _identityService.GetUserId();
user.DefaultIpAddress = _identityService.GetIpAddress();
//UserModel insertedUser = await _userService.InsertUser(user, model.Password);
UserModel insertedUser = await _userService.InsertUser(user, "TODO");
if (insertedUser != null)
{
return Ok(new GenericResultModel { Id = insertedUser.Id });
}
return Ok(new GenericResultModel(_localizer["Could_not_create_user"]));
}
}
这里的重要一点是:
var letrTryAndGetUserIdFromNameIdentifier = _identityService.GetUserId();
IdentityService
public class IdentityService : IIdentityService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public IdentityService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public int GetUserId()
{
if (_httpContextAccessor.HttpContext == null || !Authenticated())
{
throw new AuthenticationException("User is not authenticated.");
}
ClaimsPrincipal claimsPrincipal = _httpContextAccessor.HttpContext.User;
string userIdString = claimsPrincipal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
int.TryParse(userIdString, out int userIdInt);
return userIdInt;
}
public string GetIpAddress()l
{
return _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress.ToString();
}
}
在这里失败:
if (_httpContextAccessor.HttpContext == null || !Authenticated())
{
throw new AuthenticationException("User is not authenticated.");
}
目前_httpContextAccessor.HttpContext始终为null.我不确定我是否走在正确的道路上……
解决方法:
对于这种测试,您最好编写一个使用TestHost类型的集成测试,并尽可能少地进行模拟.它会更加简单,您将能够测试当前方法不支持的过滤器(如路由和授权规则).您可以在此处的文档中阅读更多内容:
https://docs.microsoft.com/en-us/aspnet/core/testing/integration-testing
我有一个很好的示例,展示了如何编写API测试,作为我在ASP.NET核心过滤器上的MSDN文章的一部分,在这里:
https://msdn.microsoft.com/en-us/magazine/mt767699.aspx
内容总结
以上是互联网集市为您收集整理的c# – .NET CORE测试 – 使用FakeItEasy模拟IHttpContextAccessor全部内容,希望文章能够帮你解决c# – .NET CORE测试 – 使用FakeItEasy模拟IHttpContextAccessor所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。