c# - net - Unit Testing Application_Start
unit test web api controller (5)
Si desea probar las acciones de un elemento basado en eventos como este, separe las acciones en un método independiente y comprobable, y simplemente llámelo desde el controlador. O, como sugirió Darin, pruebe los efectos del método: en este caso particular, su tabla de enrutamiento se registró correctamente.
Por cierto, nunca he alcanzado el 100% de cobertura en una aplicación no trivial ... En general, apuntar al 80% como "lo suficientemente bueno". Algunos módulos son 100% comprobables, pero muchos no son prácticos para hacerlo.
Estoy buscando cualquier tipo de información (prefiero Moq) sobre cómo probar el método Application_Start en Global.asax. ¡Estoy usando ASP.NET MVC y tratando de llegar a esa elusiva cobertura de código del 100%!
El hecho de que estoy usando MVC no es el punto. Y decir que no probar Start no es necesario tampoco es realmente la respuesta. ¿Qué pasa si tengo otro código allí? Necesito saber cómo probarlo.
esta función se llama la primera vez que se visita su sitio. reciclar el grupo de aplicaciones hará que se active de nuevo
En la mayoría de las situaciones, este controlador de eventos no tiene código , ¡así que no pierdas el tiempo buscando números sin sentido!
He encontrado que la mejor manera de probar la unidad en Global.asax es asegurarse de que todo esté en un método estático comprobable.
Luego, transfiera a ese método todo lo que necesita de Global.asax.
Entonces, por ejemplo, si estuviera haciendo una comprobación de Session on Application Start, podría tener un método como este:
public static void CheckSession(HttpSessionStateBase session)
{
...
}
Entonces, su inicio de aplicación sería solo esto:
protected void Application_Start(object sender, EventArgs e)
{
CheckSession(new HttpSessionStateWrapper(Session));
}
Este ejemplo es obviamente un poco tonto ya que probablemente harías algo así en Session Start :) Podrías pasar a ese método lo que necesita, Request, Response, Cache, etc.
Sin embargo, consigue el objetivo. El único código que no se cubriría sería la llamada de línea única real en Application_Start. Todo lo demás podría ser cubierto en una prueba usando Moq como tal:
var session = new Moq<HttpSessionStateBase>();
...Set Expectations...
Global.CheckSession(session.Object);
...Do Asserts...
No alcanzaría la cobertura del código del 100% que está buscando, pero estaría muy cerca, y estaría cumpliendo el "espíritu" de la ley TDD si no es exactamente la letra :)
En una aplicación ASP.NET MVC típica, el evento Application_Start se usa a menudo para registrar rutas personalizadas. Aquí hay una buena publicación que explica cómo probar sus rutas personalizadas.
Algunas organizaciones requieren esos números sin sentido y tienen problemas más allá del costo. Para las empresas que se ocupan de la información de $ 1, "lo suficientemente bueno" no es lo suficientemente bueno. Tenía exactamente el mismo problema y, como Klas Mellbourn, necesitaba llegar al 100% (¡si no más!) Lo siguiente funcionó para mí. Aunque, hubiera preferido marcarlo como "Excluir de la cobertura del código"
public class Global : HttpApplication
{
public override void Init()
{
AreaRegistration.RegisterAllAreas(); //will error out on app_start
base.Init();
}
/// <summary>
/// Application_Start method.
/// </summary>
/// <param name="sender">The caller</param>
/// <param name="e">The event arguments</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "KMM: This method is called dynamically by the framework.")]
protected void Application_Start(object sender, EventArgs e)
{
var container = StructureMapRegistry.Initialize();
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapResolver(container);
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
Entonces la prueba de la unidad se veía así:
public class GlobalTest : Global
{
private HttpRequestMessage FakeRequest;
DateTime? effectiveDate = DateTime.Now.AddYears(-4);
private string policyNumber = "1234567890";
[TestMethod]
public void ApplicationStart()
{
var sender = new object();
var e = new EventArgs();
try
{
Application_Start(sender, e); // this will error b/c not fully loaded yet.
}
catch (InvalidOperationException)
{
Thread.Sleep(2000); // give the app time to launch
Application_Start(sender, e);
}
Assert.IsTrue(true);
}
}
y finalmente, necesité establecer una bandera en mi WebApiConfig para evitar que las rutas se registraran dos veces.
public static class WebApiConfig
{
private static bool isRegistered;
/// <summary>
/// Registers the configuration.
/// </summary>
/// <param name="config">The Http Configuration.</param>
public static void Register(HttpConfiguration config)
{
if (isRegistered)
{
return;
}
config.MapHttpAttributeRoutes();
Ahora, antes de que los enemigos y puristas comiencen a marcar esto, la tarea es probar todo el código. Personalmente detestaba modificar el código para adaptarlo a las pruebas. Eso no es lo mismo que hacer que el código sea comprobable. Agregar el marcador isRegistered es un ejemplo del tipo de artefacto que es necesario para respaldar la prueba que necesita llamar a la app_start 2x. Es algo pequeño y como ese código solo se llama en app_start, no voy a preocuparme demasiado por él. Ciertamente estaría interesado en lo que otros han hecho al respecto.