Im trying to mock System.Web.Mvc.ModelStateDictionary which does not have virtual methods. So I've tried to make a sub class in this way:
public abstract class ModelStateDictionaryMock : ModelStateDictionary
{
public new abstract int Count { get; }
public new abstract bool IsReadOnly { get; }
public new abstract bool IsValid { get; }
public new abstract ICollection<string> Keys { get; }
public new abstract ICollection<ModelState> Values { get; }
public new abstract ModelState this[string key] { get; set; }
public new abstract void Add(KeyValuePair<string, ModelState> item);
public new abstract void Add(string key, ModelState value);
public new abstract void AddModelError(string key, Exception exception);
public new abstract void AddModelError(string key, string errorMessage);
public new abstract void Clear();
public new abstract bool Contains(KeyValuePair<string, ModelState> item);
public new abstract bool ContainsKey(string key);
public new abstract void CopyTo(KeyValuePair<string, ModelState>[] array, int arrayIndex);
public new abstract IEnumerator<KeyValuePair<string, ModelState>> GetEnumerator();
public new abstract bool IsValidField(string key);
public new abstract void Merge(ModelStateDictionary dictionary);
public new abstract bool Remove(KeyValuePair<string, ModelState> item);
public new abstract bool Remove(string key);
public new abstract void SetModelValue(string key, ValueProviderResult value);
public new abstract bool TryGetValue(string key, out ModelState value);
}
However when I generate a mock using var modelStateDictionary = MockRepository.GenerateMock<ModelStateDictionaryMock>();
I get an object which has a double set of properties, like this:
Doing modelStateDictionary.Count
accesses the base property, so my mock does not work. Does anyone know how to get around this problem?
You get double set of properties because you are defining the methods in your mock class as using the "new" keyword. This treats the method as a new method, and has nothing to do with the base method.
Also, because the base class method is not abstract or virtual, you really can't override it.
As for solving your mocking problem, normally there is no need to mock the ModelState
dictionary.. once you have the controller reference, you get access to its ModelState
, where you can setup the model errors etc. using the real object, and not mocking it.
Look at this post for details on how to setup errors on the Model State: How to mock ModelState.IsValid using the Moq framework?