gpt4 book ai didi

c# - 在单元测试 FormsAuthentication.SignOut() 中抛出错误

转载 作者:行者123 更新时间:2023-11-30 21:43:29 25 4
gpt4 key购买 nike

在运行我的单元测试方法时,出现错误 FormsAuthentication.SignOut()。我已经像这样 mock 了 httpcontext

var httpRequest = new HttpRequest("", "http://localhost/", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponse);
var sessionContainer = new HttpSessionStateContainer(
"id",
new SessionStateItemCollection(),
new HttpStaticObjectsCollection(),
10,
true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc,
false);
SessionStateUtility.AddHttpSessionStateToContext(httpContext, sessionContainer);
var controller = new AccountController();
var requestContext = new RequestContext(new HttpContextWrapper(httpContext), new RouteData());
controller.ControllerContext = new ControllerContext(requestContext, controller);
var actual = controller.Login(new CutomerModel() { Login = "admin", Password = "Password1" });
return httpContext;

在登录方法中

public ActionResult Login(CutomerModel obj)
{
FormsAuthentication.SignOut();
}

FormsAuthentication.SignOut(); 抛出

'Object reference not set to an instance of an object. '

最佳答案

静态方法 FormsAuthentication.SignOut 依赖于另一个静态成员 HttpContext.Current,这在单元测试期间不可用。将您的 Controller 与 HttpContext.Current 紧密耦合会导致代码很难测试。尽量避免耦合到静态调用。

旁注:难以为您的代码设置单元测试是一个明确的信号,表明它需要审查并且很可能需要重构。

抽象 FormsAuthentication 调用它们自己的关注点/接口(interface),以便可以模拟它们。

public interface IFormsAuthenticationService {

void SignOut();

//...other code removed for brevity
}

生产代码可以包装实际调用,因为 HttpContext.Current 可用。确保 DI 容器知道如何解决依赖关系。

public class FormsAuthenticationService : IFormsAuthenticationService {

public void SignOut() {
FormsAuthentication.SignOut();
}

//...other code removed for brevity

}

重构 Controller 以依赖抽象而不是实现问题。

public class AccountController : Controller {

//...other code removed for brevity.

private readonly IFormsAuthenticationService formsAuthentication;

public AccountController(IFormsAuthenticationService formsAuthentication) {
//...other arguments removed for brevity
this.formsAuthentication = formsAuthentication;
}

public ActionResult Login(CutomerModel obj) {
formsAuthentication.SignOut();
//...
return View();
}

//...other code removed for brevity.
}

与和示例测试

注意:我使用的是Moq用于模拟依赖项和 FluentAssertions用于断言结果。

[TestMethod]
public void LoginTest() {
//Arrange
var model = new CutomerModel() { Login = "admin", Password = "Password1" };
var mockFormsAuthentication = new Mock<IFormsAuthenticationService>();

var controller = new AccountController(mockFormsAuthentication.Object);

//Act
var actual = controller.Login(model) as ViewResult;

//Assert (using FluentAssertions)
actual.Should().NotBeNull(because: "the actual result should have the returned view");
mockFormsAuthentication.Verify(m => m.SignOut(), Times.Once);
}

关于c# - 在单元测试 FormsAuthentication.SignOut() 中抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41691304/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com