chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Given the following code:

class ClassWithDictionary
    {
        public Dictionary<string> TheDictionary { get; private set; }

        public ClassWithDictionary()
        {
            TheDictionary = new Dictionary<string>();
        }
    }

    class ClassUnderTest
    {
        public bool DoSomething( ClassWithDictionary param )
        {
            return param.TheDictionary.ContainsKey("toto");
        }
    }


and the following test:

[TestMethod]
        [Isolated]
        public void TestRecursiveFakeOnDictionary()
        {
            ClassWithDictionary fake = Isolate.Fake.Instance<ClassWithDictionary>(Members.ReturnRecursiveFakes);
           
            ClassUnderTest target = new ClassUnderTest();

            target.DoSomething(fake);
        }


I expected the test to pass but getting the TheDictionary property in DoSomething() returns null which results in a NullReferenceException.

Is there something I missed which would explain why a recursive fake is not returned when TheDictionary is called?
I am using version 6.0.
asked by patrick.gill@verint. (2.6k points)

7 Answers

0 votes
Hi,

The cause of the exception is that Dictionary is part of mscorlib. Isolator cannot create fakes for classes from this assembly. As a solution you can use IDictionary in your code and tests.

Regards,
Elisha,
Typemock Support
answered by Elisha (12k points)
0 votes
I overlooked that for the recursive fakes.
Thanks for quick answer.
answered by patrick.gill@verint. (2.6k points)
0 votes
Using IDictionary worked for IDictionary<string> but it does not work for IList<MyClass>.
I have another situation similar to the one on my original post except it is IList<MyClass> that needs to be returned by the recursive fake instead of IDictionary<string>. The recursive fake that should return IList<MyClass> returns null.
Is there something obvious I overlooked again?
Or is it a constraint that recursive fakes cannot return generics using reference types?
answered by patrick.gill@verint. (2.6k points)
0 votes
I found a way to make it work: MyClass was internal, if I make it public it works.
Is that expected behavior?
In the test code reproducing the problem MyClass is in the same file as the test code.
answered by patrick.gill@verint. (2.6k points)
0 votes
Hi,

You can solve it by exposing internal members to the dynamic assembly where the faked types defined.

This is the help page explains how to do it:
https://www.typemock.com/Docs/UserGuide/ ... bject.html

In general, you need to place in the assembly that defines MyClass the next attribute:
[assembly: InternalsVisibleTo("DynamicMockAssembly")]

Best Regards,
Elisha,
Typemock Support
answered by Elisha (12k points)
0 votes
I already have that attribute in the assembly defining MyClass.
And as I already mentionned I reproduced the problem with MyClass in the same file as the test class. Try the code below:

namespace TestProject1
{
    internal class MyItem
    {
        public MyItem(){}
    }

    internal class ClassToMock
    {
        public IList<MyItem> TheMyItemList { get; private set; }
        public IList<string> TheStringList { get; private set; }
    }

    internal class ClassUnderTest
    {
        public bool DoSomethingWithMyItemList(ClassToMock param)
        {
            return param.TheMyItemList.Count > 0; 
        }

        public bool DoSomethingWithStringList(ClassToMock param)
        {
            return param.TheStringList.Count > 0; 
        }
    }

    [TestClass]
    public class GenericsRecursiveFakeTest
    {
        [TestMethod]
        [Isolated]
        public void TestRecursiveFakeOnMyItemList()
        {
            ClassToMock fake = Isolate.Fake.Instance<ClassToMock>();

            ClassUnderTest target = new ClassUnderTest();

            Assert.IsFalse(target.DoSomethingWithMyItemList(fake));
        }

        [TestMethod]
        [Isolated]
        public void TestRecursiveFakeOnStringList()
        {
            ClassToMock fake = Isolate.Fake.Instance<ClassToMock>();

            ClassUnderTest target = new ClassUnderTest();

            Assert.IsFalse(target.DoSomethingWithStringList(fake));
        }
    }
}


In theory both tests should pass but TestRecursiveFakeOnMyItemList() fails because TheMyItemList returns null in return param.TheMyItemList.Count > 0;.
answered by patrick.gill@verint. (2.6k points)
0 votes
This problem was addressed (and solved) in another thread see https://www.typemock.com/community/viewtopic.php?t=1699 for details.
answered by dhelper (11.9k points)
...