MVC Controller unit test example needed.

MVC Controller unit test example needed.

Old forum URL: forums.lhotka.net/forums/t/11942.aspx


jamie.clayton posted on Friday, April 19, 2013

G'day,

I need some guidance on writing unit tests for MVC controllers. I've created a controller that populates a view correctly, allows information to be saved but fails on the [Post] UpateModel(list,collection) method. Now I suspect its related to a known CSLA bug https://github.com/MarimerLLC/csla/issues/19. , but as this architecture is not my normal solution style, I want to fall-back into unit tests to isolate the offending code.

I just can't work out how to write appropriate MVC+CLSA Controller unit tests in any sane way? Please help.

Web page example

Sample code that works around the issue.

    public class DataSchemaMappingController : Csla.Web.Mvc.Controller
    {
        /// <summary>
        /// Default page population with data entry on left and menu of alternative options on the left side of the page.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Index(int id)
        {
            ViewData.Add("Files", FinServices.Contacts.Business.DataFileList.GetAll());
            ViewData.Add("FieldDefinitions", new SelectList(FieldDefinitionList.GetAll(), "FieldDefinitionId", "FieldTitle"));
            ViewData.Model = GetListByFileId(id);

            return View();
        }

        /// <summary>
        /// Code to save the collection of data that the user could edit
        /// POST: /DataSchemaMapping/Edit/5
        /// </summary>
        /// <param name="id"></param>
        /// <param name="collection"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Index(int id, FormCollection collection)
        {
           
            ViewData.Add("Files", FinServices.Contacts.Business.DataFileList.GetAll());
            ViewData.Add("FieldDefinitions", FieldDefinitionList.GetAll());

            //  --  new SelectList(FieldDefinitionList.GetAll(), "FieldDefinitionId","FieldTitle",ModelIdea.MappedFieldDefinitionReferenceId))

            var list = GetListByFileId(id);

            //  Looks like there is a shortcoming in the CSLA MVC approach for Parent/Child collections see: https://github.com/MarimerLLC/csla/issues/19
            //UpdateModel(list, collection);   

            //  LL: Looks like this is a safe alternative to UpdateModel method above, but still fails with ChildCollection propblem.
            //TryUpdateModel(list,collection);

            int i = 0;

            //  Search through the form collection for a specific field.
            //  keys will be in the form [##].PropertyName or [GUID].PropertyName
            foreach (var key in collection.AllKeys.Where(k => k.EndsWith("MappedFieldDefinitionReferenceId")))
            {
                //   TODO: Review if we should we also be checking the [##] key prefix?
                //   ASSUMPTION: We are making an assumption that the DataPortal is retrieving Child collections in the same order, so a simple loop to populate is valid logic.
                if (collection.GetValue(key).AttemptedValue != null)
                {
                    //  TODO:   Work out how to make the left side of this generic (esentially side stepping MVC [Try]UpdateModel code).
                    listIdea.MappedFieldDefinitionReferenceId = Convert.ToInt32(collection.GetValue(key).AttemptedValue);
                }
                else
                {
                    listIdea.MappedFieldDefinitionReferenceId = null;
                }
                i++;
            }
            i = 0;
            foreach (var key in collection.AllKeys.Where(k => k.EndsWith("ColumnTitleSuppliedInDataFile")))
            {
                //   TODO: Review if we should we also be checking the [##] key prefix?
                //   ASSUMPTION: We are making an assumption that the DataPortal is retrieving Child collections in the same order, so a simple loop to populate is valid logic.
                if (collection.GetValue(key).AttemptedValue != null)
                {
                    //  TODO:   Work out how to make the left side of this generic (esentially side stepping MVC [Try]UpdateModel code).
                    listIdea.ColumnTitleSuppliedInDataFile = collection.GetValue(key).AttemptedValue.ToString();
                }
                else
                {
                    listIdea.ColumnTitleSuppliedInDataFile = null;
                }
                i++;
            }

            SaveObject(list, true);

            return View();

        }
 } 

Copyright (c) Marimer LLC