lundi 30 novembre 2015

MOQ dictionary wrapper not returning mocked content

I have a class called CacheHelper that contains a ConcurrentDictionary property. I want to mock the return values. The dictionary itself is also mocked so that it returns an object when the index getter is used. When I call the dictionary directly I get the mocked item. But when I call the CacheHelper to get the same mocked dictionary, and then call the getter on the dictionary a different item is returned. I do not understand why this is. See code below

Guid dataFileId = Guid.NewGuid();
DataFile dataFile = new DataFile() { Id = dataFileId };
var myRepo = new Mock<DataFilesRepository>();
myRepo.Object.DataFiles.Add(dataFile);
var myDict = new Mock<MockConcurrentDictionary<Guid, DataFilesRepository>>();
myDict.SetupGet(x => x[It.IsAny<Guid>()]).Returns(myRepo.Object);
var cacheHelper = new Mock<CacheHelper>();
cacheHelper.Setup(x => x.CacheDataFiles).Returns(myDict.Object);

So when I call myDict.Object[new Guid()] I get the dataFile that I put in the Setup function. When I call cacheHelper.Object.CacheDataFiles[new Guid()] I get the item that is added by default in the MockConcurrentDictionary constructor.

Extra information: I use my own MockConcurrentDictionary to be able to return true when ContainsKey is called on the dictionary. The reason for this is so I can still do my state checks in my unit test. See definition of the MockConcurrentDictionary below.

public class MockConcurrentDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>
{
    public MockConcurrentDictionary() : base(new AlwaysTrueEqualityComparer<TKey>())
    {
        // If we do not add a item to the dictionary then it will not call Equals after a ContainsKey call.
        // Our AlwaysTrueEqualityComparer would have no use than.
        TKey key = (TKey)Activator.CreateInstance((typeof(TKey)));
        TValue value = (TValue)Activator.CreateInstance((typeof(TValue)));
        this.TryAdd(key, value);
    }

    public MockConcurrentDictionary(TValue value) : base(new AlwaysTrueEqualityComparer<TKey>())
    {
        // If we do not add a item to the dictionary then it will not call Equals after a ContainsKey call.
        // Our AlwaysTrueEqualityComparer would have no use than.
        TKey key = (TKey)Activator.CreateInstance((typeof(TKey)));
        this.TryAdd(key, value);
    }

    public virtual new TValue this[TKey key]
    {
        get { return base[key]; }
        set { base[key] = value; }
    }
}

Aucun commentaire:

Enregistrer un commentaire