2010-07-15 17 views
5

Estoy comenzando en el framework Moq y me encanta. Estoy escribiendo algunas pruebas de controlador que tienen varios servicios e interfaces para organizar mi controlador para la prueba. Me encantaría modularlo un poco más, y pensé que sería una tarea trivial, pero resultó ser un poco más complicado de lo que pensaba.Pruebas del controlador Moq con configuración repetida

He aquí una prueba de unidad simple que tengo para mostrar un ejemplo:

[Test] 
public void Get_SignIn_Should_Return_View() 
{ 
    #region //TODO: figure out how to extract this out to avoid duplicate code 
    // Arrange 
    var membershipService = new Mock<IMembershipService>(); 
    var formsService = new Mock<IFormsAuthenticationService>(); 
    var userService = new Mock<IUserService>(); 
    var dictService = new Mock<IDictionaryService>(); 
    var shoppingBasketService = new Mock<IShoppingBasketService>(); 

    //Create the service provider mock and pass in the IRepositoryFactory so that it isn't instantiating real repositories 
    var repoFactory = new Mock<IRepositoryFactory>(); 
    var serviceProvider = new Mock<ServiceProvider>((IRepositoryFactory)repoFactory.Object); 

    var context = new Mock<HttpContextBase> { DefaultValue = DefaultValue.Mock }; 
    var sessionVars = new Mock<SessionVars>(); 

    AccountController controller = new AccountController(serviceProvider.Object, sessionVars.Object) 
    { 
     FormsService = formsService.Object, 
     MembershipService = membershipService.Object, 
     UserService = userService.Object, 
     DictionaryService = dictService.Object, 
     ShoppingService = shoppingBasketService.Object 
    }; 
    controller.ControllerContext = new ControllerContext() 
    { 
     Controller = controller, 
     RequestContext = new RequestContext(context.Object, new RouteData()) 
    }; 
    #endregion 

    // Act 
    ActionResult result = controller.SignIn(); 

    // Assert 
    Assert.IsInstanceOf<ViewResult>(result); 
} 

Lo que me gustaría ser capaz de hacer es tomar todo en el #region y extraer de que fuera en un método de ayuda o El método [Setup], pero si lo hago, entonces no tengo acceso a cada servicio simulado para configurar las expectativas.

¿Hay algo que me falta aquí, o realmente tengo que copiar y pegar este pedazo de código Arrange en cada prueba de unidad?

Respuesta

3

Intente utilizar un contexto para configurar todos sus simulacros, luego use test fixtures que hereda su contexto. Pon las pruebas dentro de estos accesorios y ¡violà! Es posible que este código no sea exactamente correcto para el marco que está utilizando. Si es NUnit, entonces será. Pero la teoría está ahí.

public abstract class MembershipTestContext 
    { 
     var membershipService = new Mock<IMembershipService>(); 
     var formsService = new Mock<IFormsAuthenticationService>(); 
     var userService = new Mock<IUserService>(); 
     var dictService = new Mock<IDictionaryService>(); 
     var shoppingBasketService = new Mock<IShoppingBasketService>(); 

     //Create the service provider mock and pass in the IRepositoryFactory so that it isn't instantiating real repositories 
     var repoFactory = new Mock<IRepositoryFactory>(); 
     var serviceProvider = new Mock<ServiceProvider>((IRepositoryFactory)repoFactory.Object); 

     var context = new Mock<HttpContextBase> { DefaultValue = DefaultValue.Mock }; 
     var sessionVars = new Mock<SessionVars>(); 

     [SetUp] 
     AccountController controller = new AccountController(serviceProvider.Object, sessionVars.Object) 
     { 
      FormsService = formsService.Object, 
      MembershipService = membershipService.Object, 
      UserService = userService.Object, 
      DictionaryService = dictService.Object, 
      ShoppingService = shoppingBasketService.Object 
     }; 
     controller.ControllerContext = new ControllerContext() 
     { 
      Controller = controller, 
      RequestContext = new RequestContext(context.Object, new RouteData()) 
     }; 
    } 

[TestFixture] 
public class when_getting_sign_in : MembershipContext 
{ 
    [Test] 
    public void Should_return_view() 
    { 
     // Act    
     ActionResult result = controller.SignIn(); 

     // Assert    
     Assert.IsInstanceOf<ViewResult>(result); 
    } 

    [Test] 
    public void Should_do_another_test() 
    { 
     ... another test etc 
    } 
} 
+0

Eso es lo que hago, hacer burlas a los miembros de la clase de prueba básica y tener un método de configuración común para ellos. –

1

Una cosa que podría hacer es usar el método Mock.Get (http://api.moq.me/html/C6B12927.htm) para recuperar el simulacro de una instancia de objeto determinada.
Otra opción sería refactorizar su código y almacenar referencias a sus objetos simulados en variables de instancia de su clase de prueba (si todas las pruebas en la clase de prueba lo requieren) o quizás una estructura de datos simple (si solo algunas de las pruebas los requerirá).

+0

Oh, no sabía nada de esto. Estoy seguro de que me será útil algo más adelante :) –

Cuestiones relacionadas