Tengo un servicio web que estoy tratando de probar. En el servicio, extrae varios valores de la HttpContext
misma manera:
m_password = (string)HttpContext.Current.Session["CustomerId"];
m_userID = (string)HttpContext.Current.Session["CustomerUrl"];
en la prueba unitaria, estoy creando el contexto usando una simple solicitud de trabajo, así:
SimpleWorkerRequest request = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext context = new HttpContext(request);
HttpContext.Current = context;
Sin embargo, cada vez que intento establecer los valores de HttpContext.Current.Session
HttpContext.Current.Session["CustomerId"] = "customer1";
HttpContext.Current.Session["CustomerUrl"] = "customer1Url";
Obtengo una excepción de referencia nula que dice que HttpContext.Current.Session
es nula.
¿Hay alguna forma de inicializar la sesión actual dentro de la prueba unitaria?
Respuestas:
Tuvimos que burlarnos
HttpContext
usando aHttpContextManager
y llamando a la fábrica desde nuestra aplicación, así como a las Pruebas de UnidadA continuación, reemplace las llamadas a
HttpContext.Current
conHttpContextManager.Current
y tener acceso a los mismos métodos. Luego, cuando esté probando, también puede accederHttpContextManager
y burlarse de sus expectativasEste es un ejemplo usando Moq :
y luego para usarlo dentro de sus pruebas unitarias, lo llamo dentro de mi método Test Init
luego, en el método anterior, puede agregar los resultados esperados de la sesión que espera que estén disponibles para su servicio web.
fuente
HttpContextManager
sería un nombre mejor que,HttpContextSource
pero estoy de acuerdo,HttpContextFactory
es engañoso.Puedes "simularlo" creando un nuevo
HttpContext
como este:http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx
Tomé ese código y lo puse en una clase auxiliar estática así:
O en lugar de usar la reflexión para construir la nueva
HttpSessionState
instancia, simplemente puede adjuntar suHttpSessionStateContainer
a laHttpContext
(según el comentario de Brent M. Spell):y luego puedes llamarlo en tus pruebas unitarias como:
fuente
Server.MapPath()
no funcionará si usa esto tampoco.La solución Milox es mejor que la aceptada en mi humilde opinión, pero tuve algunos problemas con esta implementación al manejar las URL con la cadena de consulta .
Hice algunos cambios para que funcione correctamente con cualquier URL y para evitar Reflection.
fuente
httpContext.Session
, ¿alguna idea de cómo hacer lo mismohttpContext.Application
?Me preocupa algo sobre esto hace un tiempo.
Prueba de unidad HttpContext.Current.Session en MVC3 .NET
Espero eso ayude.
fuente
Si está utilizando el marco MVC, esto debería funcionar. Solía del Milox FakeHttpContext y añadí unas pocas líneas de código adicionales. La idea surgió de esta publicación:
http://codepaste.net/p269t8
Esto parece funcionar en MVC 5. No he probado esto en versiones anteriores de MVC.
fuente
Puedes probar FakeHttpContext :
fuente
En asp.net Core / MVC 6 rc2 puede configurar el
HttpContext
rc 1 era
https://stackoverflow.com/a/34022964/516748
Considere usar
Moq
fuente
La respuesta que funcionó conmigo es lo que @Anthony había escrito, pero debe agregar otra línea que es
para que puedas usar esto:
fuente
Prueba esto:
Y agregue la clase:
Esto le permitirá probar con sesión y caché.
fuente
Estaba buscando algo un poco menos invasivo que las opciones mencionadas anteriormente. Al final se me ocurrió una solución cursi, pero podría hacer que algunas personas se muevan un poco más rápido.
Primero creé una clase TestSession :
Luego agregué un parámetro opcional al constructor de mi controlador. Si el parámetro está presente, úselo para la manipulación de la sesión. De lo contrario, use HttpContext.Session:
Ahora puedo inyectar mi TestSession en el controlador:
fuente
Nunca te burles ... nunca! La solución es bastante simple. ¿Por qué simular una creación tan hermosa
HttpContext
?Empuje la sesión hacia abajo! (Solo esta línea es suficiente para que la mayoría de nosotros la comprendamos, pero se explica en detalle a continuación)
(string)HttpContext.Current.Session["CustomerId"];
así es como accedemos ahora. Cambia esto aCuando se llama desde la prueba, _customObject utiliza una tienda alternativa (DB o valor de clave de nube [ http://www.kvstore.io/] )
Pero cuando se llama desde la aplicación real,
_customObject
utilizaSession
.como se hace esto bueno ... ¡Inyección de dependencia!
Por lo tanto, la prueba puede configurar la sesión (subterránea) y luego llamar al método de aplicación como si no supiera nada sobre la sesión. Luego, la prueba comprueba en secreto si el código de la aplicación actualizó correctamente la sesión. O si la aplicación se comporta en función del valor de sesión establecido por la prueba.
En realidad, terminamos burlándonos aunque dije: "nunca te burles". Porque no pudimos evitar pasar a la siguiente regla, "¡burlarse de donde menos duele!". Burlándose de
HttpContext
una sesión pequeña o enorme , ¿qué duele menos? no me preguntes de dónde vinieron estas reglas. Digamos simplemente sentido común. Aquí hay una lectura interesante sobre no burlarse, ya que la prueba unitaria puede matarnosfuente
La respuesta que me dio @Ro Hit me ayudó mucho, pero me faltaban las credenciales de usuario porque tenía que falsificar a un usuario para la prueba de la unidad de autenticación. Por lo tanto, permítanme describir cómo lo resolví.
De acuerdo con esto , si agrega el método
y luego anexar
hasta la última línea del
TestSetup
método que haya terminado, las credenciales de usuario se agregan y están listas para usarse para las pruebas de autenticación.También noté que hay otras partes en HttpContext que podría necesitar, como el
.MapPath()
método. Hay un FakeHttpContext disponible, que se describe aquí y se puede instalar a través de NuGet.fuente
Encontré la siguiente solución simple para especificar un usuario en el HttpContext: https://forums.asp.net/post/5828182.aspx
fuente
Intenta de esta manera ...
fuente