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
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I have the following simple classes:

    public class ClassA
    {
    }

    public class ClassB
    {
    }

    public static class GenericClass<X> where Y : IList<X>, new()
    {
        public static Y GetCollection(X x)
        {
            var y = new Y();
            y.Add(x);
            return y;
        }
    }

    public static class NonGenericClass
    {
        public static Y GetCollection<X>(X x) where Y : IList<X>, new()
        {
            var y = new Y();
            y.Add(x);
            return y;
        }
    }


and two tests:

        [Test, Isolated]
        public void Test1()
        {
            var fakeA = new List<ClassA>();
            Isolate.WhenCalled(() => GenericClass<ClassA, List<ClassA>>.GetCollection(null)).WillReturn(fakeA);

            var fakeB = new List<ClassB>();
            Isolate.WhenCalled(() => GenericClass<ClassB, List<ClassB>>.GetCollection(null)).WillReturn(fakeB);
        }

        [Test, Isolated]
        public void Test2()
        {
            var fakeA = new List<ClassA>();
            Isolate.WhenCalled(() => NonGenericClass.GetCollection<ClassA, List<ClassA>>(null)).WillReturn(fakeA);

            var fakeB = new List<ClassB>();
            Isolate.WhenCalled(() => NonGenericClass.GetCollection<ClassB, List<ClassB>>(null)).WillReturn(fakeB);
        }


Both of them fail with the following error:

System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.List`1[Lfx.Global.Tests.Unit.ClassA]' to type 'System.Collections.Generic.List`1[Lfx.Global.Tests.Unit.ClassB]'.

They fail on the second WhenCalled statement and only if both WhenCalled statements included. It's no problem to fake each of them separately.

Looks like Isolator gets somewhat gets confused by methods' signatures and tries to use first fake in the second statement causing invalid cast exception.

I have more complex code where this happens, I made this trivial example to show simplify reproducing of this bug.

Good luck!
asked by vagif (19.4k points)

7 Answers

0 votes
Hi Vagif

Thanks for the excellent repro.
It indeed looks like a bug :twisted:
We'll let you know as soon as it's fixed.
answered by ohad (35.4k points)
0 votes
I noticed there was a new version (5.2.3) in download section, installed it and tried the example above. Still the same bug. Wasn't this fixed in 5.2.3?
answered by vagif (19.4k points)
0 votes
I have just installed v5.2.3.0 (fresh install, no previous version)
and am having a similar problem with non-static calls. Is this the same bug?
Is there a work-around using the older API?
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Class1 c = Isolate.Fake.Instance<Class1>();
            c1 x1 = new c1();
            Isolate
                .WhenCalled<c1>(() => c.Method<c1>())
                .WillReturn(x1);
            c2 x2 = new c2();
            //next line throws exception:
            //Test method TestProject1.UnitTest1.TestMethod1 threw exception:  
            //System.Reflection.TargetInvocationException: 
            // Exception has been thrown by the target of an invocation. --->  
            // System.InvalidCastException: Unable to cast object
            // of type 'TestProject1.c1' to type 'TestProject1.c2'..
            Isolate
                .WhenCalled<c2>(() => c.Method<c2>())
                .WillReturn(x2);
            Assert.AreEqual(x1, c.Method<c1>(), "first");
            Assert.AreEqual(x2, c.Method<c2>(), "second");
        }
    }
    public class Class1
    {

        public T Method<T>() where T : class, new()
        {
            T c = new T();

            return c;
        }
    }

    public class c1
    {
    }
    public class c2
    {
    }
answered by andredking (800 points)
0 votes
This seems to work for me:

        [TestMethod]
        public void TestMethod2()
        {
            MockManager.Init();
            Mock mock = MockManager.Mock<Class1>();
            c1 x1 = new c1();
            mock.ExpectAndReturn("Method", x1, typeof(c1));
            c2 x2 = new c2();
            mock.ExpectAndReturn("Method", x2, typeof(c2));

            Class1 c = new Class1();

            Assert.AreSame(x1, c.Method<c1>(), "first");
            Assert.AreSame(x2, c.Method<c2>(), "second");
answered by andredking (800 points)
0 votes
Hi Andre

The bug was fixed in version 5.3.0 that came out yesterday. 8)
The first test using AAA syntax should work now.
Please try it and tell me if it solves the problem.
answered by ohad (35.4k points)
0 votes
Yup, works now :)
Thanks a bunch,
a
answered by andredking (800 points)
0 votes
I too had the same problem last week (and found this post describing it). Works great now with 5.3.0! :D
answered by jberd126 (760 points)
...