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
I have a litte problem to UnitTest my Class.
 public sealed class Class1
{
        private Class2 _cachedClass2;
        public long Class2Id { get; set; }
        public Class2 LinkedClass2
        {
            get
            {
                if (_cachedClass2 == null) //<-Problem
                {
                    LoadClass2();
                }
                return _cachedClass2;
            }
        }
        private void LoadClass2()
        {
            _cachedClass2 = new Class2(Class2Id);
            _cachedClass2.Load();
        }
}

My UnitTest Code is
Class2 faked = Isolate.Fake.Instance<Class2>(Members.ReturnRecursiveFakes);
Isolate.Swap.NextInstance<Class2>().With(faked);
Class1 target = new Class1();
target.Class2Id = 2L;
Class2 result = target.LinkedClass2;
Assert.AreEqual(2L, result.Id);


My Problem is that the Instance is swaped when calling the LinkedClass2 property so the if statement is always false. I think the swaping should only take place when I create the instance with new.

However if this works as expected how do I swap only the instances created with the new statement. :?:
asked by swtrse (4k points)

5 Answers

0 votes
Well I found out if I do not set beakpoints and don't use single step mode while checking the values of the variables all is working fine.
answered by swtrse (4k points)
0 votes
I've tried running the code you supplied and it seems to work fine.
Let me see if I understand the flow:
1. Create fake instance of Class2
2. Use Swap to replace the fake with a future object
3. Create a real Class1
4. Set a Property on Class1
5. call Class1.LinkedClass
6 .Inside LinkedClass - check if _cachedClass2 is null - It is!
7. Create a new Class2 (this is where swap kicks in) and call Class2.Load

It worked the same with or without a breakpoint. The assert will always fail because class2 is faked and the parameter passed to its c'tor has no effect on it.

You can use the following code to make sure that the code inside the if statement is always called:
Class2 faked = Isolate.Fake.Instance<Class2>(Members.ReturnRecursiveFakes);
Isolate.Swap.NextInstance<Class2>().With(faked);
Class1 target = new Class1();

target.Class2Id = 2L;
Class2 result = target.LinkedClass2;
Isolate.Verify.WasCalledWithAnyArguments(() => faked.Load());
answered by dhelper (11.9k points)
0 votes
Well the actual classes are a bit more complicated.
Since I had some time I found out a few more things.

1) The cached Values are working fine as long as the Autos window (Debug->Windows->Autos OR Ctrl+Alt+V, A) is not activated while debuging. So this seems to be an VS2008 Problem and no Typemock problem.

2) I write a litte test-Solution do reproduce this case. While testing around I found an litte odd thing with the swap command.
The it looks like the swap command did not swap at all in this case.

Class2 fake = new Class2(4L);
            Isolate.Swap.NextInstance<Class2>().With(fake);
            Isolate.WhenCalled(() => fake.Load()).IgnoreCall();

            Class1 target = new Class1(2L) { Class2Id = 3L };
            Class2 result = target.LinkedClass2;
            Isolate.Verify.WasCalledWithAnyArguments(() => fake.Load()); //<-Works
            Assert.AreEqual(4L, result.Class2Id); //Fails

With the Swap and the given code I would expect that Class2Id is 4, but it's 3 so there is no swaping. I tried swap AllInstances too but without any effect.

The Solution is available at http://www.schoeller-soft.net/TestConsole.7z
answered by swtrse (4k points)
0 votes
Just to be complete.
I use Typemock Isolator 5.4.5.0

The variant with
Class2 fake = Isolate.Fake.Instance<Class2>(Members.ReturnRecursiveFakes, ConstructorWillBe.Called, 4L);
Isolate.Swap.NextInstance<Class2>().With(fake);

is not working too.
This gives an exception when the code reaches the new Class2 command in the LoadClass2() method.
answered by swtrse (4k points)
0 votes
The Swap method doesn't actually swap the instance only its behavior - this is why the internal value was not correct.

As for the other problem you've encountered - I'd like to investigate it offline please send a project that reproduce this issue to our support email (support AT typemock.com).
answered by dhelper (11.9k points)
...