He respondido mi propia pregunta Soy bastante nuevo en la prueba de unidad. Estoy intentando realizar una prueba muy básica. "/ home / Index" . pero falla debido a la comprobación de sesión.

SessionManager es una clase que existe en el modelo.

using EPS.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EPS.Controllers
{

    public class HomeController : Controller
    {

        public ActionResult Index()
        {

            if (!SessionManager.IsUserLoggedIn || SessionManager.CurrentUser.EmployeeId == 0)
            {
                return RedirectToAction("Index", "Login");
            }
            else if (Session["UserType"] == "ADMIN")
            {
                return View(); //we have to run this view than test will pass
            }
            else
                return HttpNotFound();
        }
}

Si comento si la declaración y el cuerpo que el resultado de la prueba como pase.

el código de prueba es.

using EPS;
using EPS.Models;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using MvcContrib.TestHelper;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Mail;
using FakeHttpContext;
using System.Web;
using System.Web.Mvc;
using EPS.Controllers;

namespace EPS.test
{
    [TestClass]
    public class ControllerTest
    {

        [TestMethod]
        public void Index()
        {           
            //arrange
            HomeController controller = new HomeController();
           //Act
            ViewResult result= controller.Index() as ViewResult;
            //Assert
            Assert.IsNotNull(result);
        }
    }
}

Aquí está la clase Administrador de sesión que estoy usando para mantener la sesión

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Collections;

namespace EPS.Models
{
    public static class SessionManager
    {
        #region Private Data

        private static String USER_KEY = "user";

        #endregion

        public static Employee CurrentUser
        {
            get;
            set;
        }
        public static string UserType
        {
            get;
            set;
        }
        public static Int32 SessionTimeout
        {
            get
            {
                return System.Web.HttpContext.Current.Session.Timeout;
            }
        }

        public static String GetUserFullName()
        {
            if (SessionManager.CurrentUser != null)
                return SessionManager.CurrentUser.FirstName;
            else
                return null;
        }
        public static Boolean IsUserLoggedIn
        {
            get
            {
                if (SessionManager.CurrentUser != null)
                    return true;
                else
                    return false;
            }
        }
        #region Methods
        public static void AbandonSession()
        {
            for (int i = 0; i < System.Web.HttpContext.Current.Session.Count; i++)
            {
                System.Web.HttpContext.Current.Session[i] = null;
            }
            System.Web.HttpContext.Current.Session.Abandon();
        }

        #endregion
    }
}
0
user5407401 18 ene. 2018 a las 10:10

3 respuestas

La mejor respuesta

He resuelto mi problema sin inyecciones de dependencia. La solución está aquí. MVC 5 viene de un paquete NuGet. Tal como lo hizo con el proyecto web MVC principal en su solución. Instale MVC, moq, RhinoMock a través de NuGet en su proyecto de prueba, y estará listo para comenzar. funcionó para mí crear variable de sesión

Session ["Usertype"] = "ADMINISTRADOR"

Y creando un usuario actual. he generado un

SessionManager.CurrentUser = usuario

Verdad

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MyUnitTestApplication;
using MyUnitTestApplication.Controllers;
using MyUnitTestApplication.Models;
using Moq;
using System.Security.Principal;
using System.Web;
using System.Web.Routing;
//using Rhino.Moq;
using Rhino.Mocks;


 namespace MyUnitTestApplication.Tests.Controllers
    {
        [TestClass]
        public class HomeControllerTest
        {
            [TestMethod]
            public void TestActionMethod()
            {
                Employee User = new Employee();
                User.FirstName = "Ali";
                User.EmployeeId = 1;
                SessionManager.CurrentUser = User;
     var fakeHttpContext = new Mock<HttpContextBase>();
      var sessionMock = new Mock<HttpSessionStateBase>();
                sessionMock.Setup(n => n["UserType"]).Returns("ADMIN");
                sessionMock.Setup(n => n.SessionID).Returns("1");
     fakeHttpContext.Setup(n => n.Session).Returns(sessionMock.Object);
     var sut = new HomeController();
                sut.ControllerContext = new ControllerContext(fakeHttpContext.Object, new RouteData(), sut);
                ViewResult result = sut.TestMe() as ViewResult;
                Assert.AreEqual(string.Empty, result.ViewName);
    }
    }
    }
0
26 ene. 2018 a las 11:12

Su prueba está fallando debido al administrador de sesión. Esta vez el Administrador de sesión es nulo. Para la prueba unitaria, debe proporcionar una implementación falsa de Session Manager. Para hacer esto, necesita aprender DI y cómo burlarse de un objeto.

0
Ehasanul Hoque 18 ene. 2018 a las 07:34

En primer lugar, la estática a veces es difícil de probar. así que debes cambiar SessionManager

public class SessionManager : ISessionManager
{
    #region Private Data

    private static String USER_KEY = "user";

    #endregion

    public Employee CurrentUser
    {
        get
        {
            return (Employee)System.Web.HttpContext.Current.Session[USER_KEY];
        }
    }
    public string UserType
    {
        get { return (string) System.Web.HttpContext.Current.Session["USER_TYPE"]; }
    }
    public Int32 SessionTimeout
    {
        get
        {
            return System.Web.HttpContext.Current.Session.Timeout;
        }
    }

    public String GetUserFullName()
    {
        if (CurrentUser != null)
            return CurrentUser.FirstName;
        else
            return null;
    }
    public Boolean IsUserLoggedIn
    {
        get
        {
            if (CurrentUser != null)
                return true;
            else
                return false;
        }
    }
    #region Methods
    public void AbandonSession()
    {
        for (int i = 0; i < System.Web.HttpContext.Current.Session.Count; i++)
        {
            System.Web.HttpContext.Current.Session[i] = null;
        }
        System.Web.HttpContext.Current.Session.Abandon();
    }

    #endregion
}

Mira estos dos artículos sobre inyecciones de dependencia https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection

https://msdn.microsoft.com/en-us/library/ff647854.aspx

Básicamente configuré todas las clases que necesitan ISessionManager para completar SessionManager y también lo configuré para que sea "Singleton" para que haya compartido la instancia de SessionManager para todos los controladores que lo necesiten.

Clase Bootstrapper (inicialícela desde su App_Start)

public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();   

        RegisterTypes(container);

        return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {
        // Singleton lifetime.   
        container.RegisterType<ISessionManager, SessionManager>(new ContainerControlledLifetimeManager());
    }
}

Clase HomeController

public class HomeController : Controller
{
    private readonly ISessionManager _sessionManager;

    public HomeController(ISessionManager sessionManager)
    {
        _sessionManager = sessionManager;
    }

    public ActionResult Index()
    {

        if (!_sessionManager.IsUserLoggedIn || _sessionManager.CurrentUser.EmployeeId == 0)
        {
            return RedirectToAction("Index", "Login");
        }
        else if (_sessionManager.UserType == "ADMIN")
        {
            return View(); //we have to run this view than test will pass
        }
        else
            return HttpNotFound();
    }
}

Clase de prueba (eche un vistazo a https://github.com/Moq/moq4/wiki/Quickstart)

[TestClass()]
public class HomeControllerTests
{
    [TestMethod()]
    public void IndexTest()
    {
        // Arrange
        Employee user = new Employee()
        {
            EmployeeId = 1,
            FirstName = "Mike"
        };
        var simulatingLoggedUser = new Mock<ISessionManager>();
        simulatingLoggedUser.Setup(x => x.CurrentUser).Returns(user);
        simulatingLoggedUser.Setup(x => x.UserType).Returns("ADMIN");
        simulatingLoggedUser.Setup(x => x.IsUserLoggedIn).Returns(true);

        HomeController homeController = new HomeController(simulatingLoggedUser.Object);

        // Act
        var result = homeController.Index() as ViewResult;

        //Assert
        Assert.IsNotNull(result);
    }
}
1
Nkosi 18 ene. 2018 a las 17:04