Asp.net core session unit test
我有问题,与ASP.NET MVC的控制器单元测试的核心。那是我的问题:我使用的会话控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [HttpPost] public IActionResult OpretLobby(LobbyViewModel lobby) { try { //find brugeren der har lavet lobby var currentUser = HttpContext.Session.GetObjectFromJson<User>("user"); //save as a lobby ILobby nyLobby = new Lobby(currentUser.Username) { Id = lobby.Id }; SessionExtension.SetObjectAsJson(HttpContext.Session, lobby.Id, nyLobby); //add to the list _lobbyList.Add(nyLobby); return RedirectToAction("Lobby","Lobby",lobby); } |
本厂perfectly全井的在线服务器,这里没什么错。但当它吃的东西全单元测试需求(这不是完美的,它的操作系统了。
basicly的问题是,我不能把我从访问的测试会话。在许多方面,我有一个很mocks创建不到什么,但大多数.NET框架的解决方案和不工作的核心,是.NET的一些原因。请帮助我在痛苦!
注意:
我使用的版本的虚拟试验对分离这一问题:
1 2 3 4 5 6 7 8 9 | [Test] public void TestIsWorking() { SessionExtension.SetObjectAsJson(uut.HttpContext.Session,"user", _savedUser); //ViewResult result = uut.OpretLobby(lobbyViewModel) as ViewResult; //Assert.AreEqual("OpretLobby", result.ViewName); Assert.AreEqual(1,1); } |
这里的错误也会想设置会话的用户。
似乎
我通常为这种场景创建一个抽象。然后在DI容器中注册它,并将依赖项注入控制器。
创业公司1 2 3 4 5 6 7 8 9 10 11 12 | public class Startup { ... public void ConfigureServices(IServiceCollection services) { ... services.AddScoped<IUserSession, UserSession>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); ... } ... } |
抽象化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class User { public string Username { get; set; } } public interface IUserSession { User User { get; } } public class UserSession : IUserSession { private readonly IHttpContextAccessor _httpContextAccessor; public UserSession(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public User User => _httpContextAccessor.HttpContext.Session.GetObjectFromJson<User>("user"); } public static class SessionExtensions { public static User GetObjectFromJson<User>( this ISession sesson, string json) where User : new() { return new User(); // Dummy extension method just to test OP's code } } |
控制器2
}
单元测试1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using AspNetCore.Controllers; using Microsoft.AspNetCore.Mvc; using Moq; using Xunit; namespace XUnitTestProject1 { public class HomeControllerTests { private readonly User _user; public HomeControllerTests() { _user = new User {Username ="johndoe"}; } [Fact] public void OpretLobby_Test() { // Arrange var mockUserSession = new Mock<IUserSession>(); mockUserSession.Setup(x => x.User).Returns(_user); var sut = new HomeController(mockUserSession.Object); // Act var result = sut.OpretLobby(); // Assert var viewResult = Assert.IsType<ViewResult>(result); var user = Assert.IsType<User>(viewResult.Model); Assert.Equal(_user.Username, user.Username); } } } |
@尼古拉斯·拉德福格
嘿,我建议您在需要从会话中获取一些内容时使用集成测试
ASP.NET核心有一个很棒的
尝试添加以下代码段
1 2 3 4 5 6 7 8 9 |
干得好!你将有一个真正的课程,你可以测试
顺便说一句,moq库没有模拟静态方法的能力,所以存在很多问题。我认为在您的情况下使用集成测试会更容易一些
祝你好运!
胜利解决了!这是最后的测试代码,如果有人想知道的话!谢谢!
1 2 3 4 5 6 7 8 9 10 | // Arrange var mockUserSession = new Mock<IUserSession>(); mockUserSession.Setup(x => x.User).Returns(_savedUser); var sut = new LobbyController(FakeSwagCommunication,mockUserSession.Object); // Act var result = sut.OpretLobby(_lobbyViewModel); // Assert Assert.IsInstanceOf<RedirectToActionResult>(result); |
按照win所说的那样做之后,我得到的viewresult为空。
单元测试桩法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | [Test] public void OpretLobby_Post() { // Arrange var mockUserSession = new Mock<IUserSession>(); mockUserSession.Setup(x => x.User).Returns(_savedUser); var sut = new LobbyController(FakeSwagCommunication,mockUserSession.Object); // Act var result = sut.OpretLobby(_lobbyViewModel) as ViewResult; // Assert //var user = (User)result.Model; Assert.AreEqual("Lobby",result.ViewName); } |
柱法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | [HttpGet] public IActionResult OpretLobby() { return View("OpretLobby"); } [HttpPost] public IActionResult OpretLobby(LobbyViewModel lobby) { try { //find brugeren der har lavet lobby var currentUser = _userSession.User; //save as a lobby ILobby nyLobby = new Lobby(currentUser.Username) { Id = lobby.Id }; //SessionExtension.SetObjectAsJson(HttpContext.Session, lobby.Id, nyLobby); //add to the list _lobbyList.Add(nyLobby); return RedirectToAction("Lobby","Lobby",lobby); } catch (ArgumentException) { return RedirectToAction("OpretLobby"); } } |
会话扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public interface IUserSession { User User { get; set; } } public class UserSession : IUserSession { private readonly IHttpContextAccessor _httpContextAccessor; public UserSession(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public User User { get => _httpContextAccessor.HttpContext.Session.GetObjectFromJson<User>("user"); set => _httpContextAccessor.HttpContext.Session.SetObjectAsJson("user", value); } } public static class SessionExtension { public static void SetObjectAsJson(this ISession session, string key, object value) { session.SetString(key, JsonConvert.SerializeObject(value)); } public static T GetObjectFromJson<T>(this ISession session, string key) { var value = session.GetString(key); return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value); } } |
希望你能帮得上忙