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
This is continuation of my previous post about mocking a constructor, but I think it deserves a new post with a new name, because this is in fact not about mocking a constructor, but about swapping arguments in a call to an object constructor. Let's see we have a simple class:

    public class MyClass
    {
        public string A;
        public string B;

        public MyClass(string a, string b)
        {
            A = a;
            B = b;
        }

        public string Concat()
        {
            return A + B;
        }
    }


What I need to in the test is to a create an instance of MyClass with arguments "e" and "f" passed to a constructor. Let's say it's difficult to establish test environment where "e" and "f" are passed during the test, so I want to swap arguments that are sent to a constructor.

First, if I simply mock the constructor then its fields will not be assigned at all, this is how it should be:

            using (RecordExpectations recorder = new RecordExpectations())
            {
                theClass = new MyClass("e", "f");
            }
            theClass = new MyClass("a", "b");
            Assert.IsNull(theClass.A);
            Assert.IsNull(theClass.B);


So I am trying to use what Eli suggested yesterday: swap arguments using CheckArguments call:

            using (RecordExpectations recorder = new RecordExpectations())
            {
                theClass = new MyClass("c", "d");
                recorder.CheckArguments(new Assign("e"), new Assign("f"));
            }
            theClass = new MyClass("a", "b");
            // This will fail! Fields are still null!!!
            Assert.AreEqual("e", theClass.A);
            Assert.AreEqual("f", theClass.B);


But it does not work! As you see in the code comments above, fields are not assigned even after a call to CheckArguments.

The only thing that I found working was not using natural mocks and calling ExpectUnmockedConstructor:

            Mock theMock = MockManager.Mock(typeof(MyClass));
            theMock.ExpectUnmockedConstructor().Args(new Assign("e"), new Assign("f"));
            theClass = new MyClass("a", "b");
            Assert.AreEqual("e", theClass.A);
            Assert.AreEqual("f", theClass.B);
            Assert.AreEqual("ef", theClass.Concat());


So at least there is a workaround not using natural mocks. But I would like to use it with RecordExpectations. Is this possible?
asked by vagif (19.4k points)

2 Answers

0 votes
:idea: We have to tell Typemock to call the original method.

using (RecordExpectations recorder = new RecordExpectations())
{
   theClass = new MyClass("c", "d");
   recorder.CallOriginal.CheckArguments(new Assign("e"), new Assign("f"));
}
answered by eli (5.1k points)
0 votes
Wow! It now works, works, works!

Thanks Eli! It's not just me who is crazy enough to write code on Saturdays :D
answered by vagif (19.4k points)
...