Question

I have written Custom model binder for my MVC3 application. I desided to use the Custom model binder is because I am using Sessions and unit tests are failing because of them.

Now my problem is that About action does not accept any parameter but it need to pass the values stored in cart to view without using Session. Because with session it will fail the unit test. Model binder only works if I pass the cart as parameter to About.

Please suggest me if you have any ideas.

many Thanks

Model Binder

public class CartModelBinder : IModelBinder
{
    private const string CartSessionKey = "Cart";

    public object BindModel(ControllerContext controllerContext, ModelBindingContext modelBindingContext)
    {
        Cart cart = null;

        if(IsCartExistInSession(controllerContext))
        {
            cart = GetCartFromSession(controllerContext); 
        }
        else
        {
            cart = new Cart();
            AddCartToSession(controllerContext, cart);
        }
        return cart;
    }

    private static Cart GetCartFromSession(ControllerContext controllerContext)
    {
        return controllerContext.HttpContext.Session[CartSessionKey] as Cart;
    }

    private static void AddCartToSession(ControllerContext controllerContext, Cart cart)
    {
        controllerContext.HttpContext.Session[CartSessionKey] = cart;
    }

    private static bool IsCartExistInSession(ControllerContext controllerContext)
    {
        return controllerContext.HttpContext.Session[CartSessionKey] != null;
    }       
}

Controller

[HttpPost]
public ActionResult AddToCartfromAbout(Cart cart, int productId = 2)
{
    var product = _productRepository.Products.First(p => p.ProductId == productId);
    cart.AddItem(product, 1);
    return View("About");
}

public ActionResult About()
{ 
    // Need something here to get the value of cart 
    return View(cart);
}
Was it helpful?

Solution

This Link may solve you problem. You need to download the source and DLLs from the link above and them you can assign the value to Session in Test.

[Test]
public void AddSessionStarShouldSaveFormToSession()
{
    // Arrange
    TestControllerBuilder builder = new TestControllerBuilder();
    StarsController controller = new StarsController();
    builder.InitializeController(controller);
    controller.HttpContext.Session["NewStarName"] = "alpha c";

    // Act
    RedirectResult result = controller.Index() as RedirectResult;

    // Assert
    Assert.IsTrue(result.Url.Equals("Index"));
} 

OTHER TIPS

I would suggest use Moq (or any other tool for mocking your data) and pass the values on the controller constructor. (Not sure, but mabe use Dependency Injection would help on this if it is not too much over-engineering)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top