Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试表单SAuthentication.SignOut()中抛出错误_C#_Unit Testing_Mocking_Httprequest_Forms Authentication - Fatal编程技术网

C# 单元测试表单SAuthentication.SignOut()中抛出错误

C# 单元测试表单SAuthentication.SignOut()中抛出错误,c#,unit-testing,mocking,httprequest,forms-authentication,C#,Unit Testing,Mocking,Httprequest,Forms Authentication,在运行我的单元测试方法时,我从sauthentication.SignOut()中得到错误。我曾经这样嘲笑过httpcontext var httpRequest = new HttpRequest("", "http://localhost/", ""); var stringWriter = new StringWriter(); var httpResponse = new HttpResponse(stringWriter); var httpContext = new HttpCont

在运行我的单元测试方法时,我从sauthentication.SignOut()中得到错误。我曾经这样嘲笑过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()抛出

“对象引用未设置为对象的实例。”


静态方法
用于身份验证。注销
依赖于另一个静态成员
HttpContext.Current
,该成员在单元测试期间不可用。将控制器与HttpContext紧密耦合。当前的
是静态的,这会导致代码很难测试。尽量避免耦合到静态调用

旁注:在为代码设置单元测试时遇到困难是一个明确的迹象,表明需要对其进行审查和重构

抽象
FormsAuthentication
调用它们自己的关注点/接口,以便可以对它们进行模拟

public interface IFormsAuthenticationService {

    void SignOut();

    //...other code removed for brevity
}
生产代码可以包装实际调用,该调用应作为
HttpContext工作。当前的
随后可用。确保DI容器知道如何解决依赖关系

public class FormsAuthenticationService : IFormsAuthenticationService {

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

    //...other code removed for brevity

}
重构控制器,使其依赖于抽象而不是实现问题

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.
}
和示例测试

注意:我用于模拟依赖项和断言结果

[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);
}
[TestMethod]
公共无效登录测试(){
//安排
var model=new-cutomemodel(){Login=“admin”,Password=“Password1”};
var mockFormsAuthentication=new Mock();
var控制器=新的AccountController(mockFormsAuthentication.Object);
//表演
var actual=controller.Login(model)作为ViewResult;
//断言(使用FluentAssertions)
actual.Should().NotBeNull(因为:“实际结果应该有返回的视图”);
mockFormsAuthentication.Verify(m=>m.SignOut(),Times.Once);
}

工作正常。谢谢