I was trying to write unit tests in ASP.NET MVC2 against action methods that call UpdateModel() or TryUpdateModel() and I kept getting the exception below from the MVC framework in the controller class:
System.ArgumentNullException: Value cannot be null.
Parameter name: collection
Here is the offending MVC source:
protected internal bool TryUpdateModel<TModel>(TModel model, string prefix) where TModel : class {
return TryUpdateModel(model, prefix, null, null, ValueProvider);
}
ValueProvider was returning null despite my best efforts to mock the HttpRequest object in the controller’s context (as seen in a bazillion examples online). As it turns out, in MVC2, you now have to create a ValueProviderCollection and assign it directly to your controller in order to mock the form post. The following code does the trick:
private static ValueProviderCollection SetupValueProvider(Dictionary<string, string> formValues)
{
List<IValueProvider> valueProviders = new List<IValueProvider>();
FormCollection form = new FormCollection();
if (formValues != null)
{
foreach (string key in formValues.Keys)
{
form.Add(key, formValues[key]);
}
}
valueProviders.Add(form);
return new ValueProviderCollection(valueProviders);
}
Call it during your test setup like this:
controller.ValueProvider = SetupValueProvider(formValues);