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
Hello,

I need to mock a string field of a type that is constructed by parsing a string. A simplified version of the type with two tests is listed below:


        public class MyType
        {
            public string MyField { get; set; }

            public static MyType Parse(string s)
            {
                MyType t = new MyType();
                t.MyField = s;
                return t;
            }
        }

        [Test]
        [VerifyMocks]
        public void MyType_Simple()
        {
            MyType mockedType = new MyType();
            using (RecordExpectations recorder = new RecordExpectations())
            {
                recorder.ExpectAndReturn(mockedType.MyField, "abc").RepeatAlways();
            }

            mockedType.MyField = "xyz";
            Assert.AreEqual("abc", mockedType.MyField);
        }

        [Test]
        [VerifyMocks]
        public void MyType_Parsed()
        {
            MyType mockedType = new MyType();
            using (RecordExpectations recorder = new RecordExpectations())
            {
                recorder.ExpectAndReturn(mockedType.MyField, "abc").RepeatAlways();
            }

            mockedType = MyType.Parse("xyz");
            Assert.AreEqual("abc", mockedType.MyField);
        }


I expect both tests to succeed, however the second one fails! It keeps MyField value to be "xyz", but there is a recorder statement that mocks any access to MyField property. Why does this happen?

Thanks in advance

Vagif Abilov
Oslo Norway
asked by vagif (19.4k points)

3 Answers

0 votes
I noticed that if in the second test I move the line with a constructor ("MyType mockedType = new MyType();") into a mock recorder body, then the test succeeds. With the first test it is not necessary. I wonder what makes the difference.
answered by vagif (19.4k points)
0 votes
Hi Vagif,

In both tests, you are using expectations on a future mock. That means that the expectation will be on the next generated object.

In the first case, you set the expectation on an already created object. That's the object you created prior to the recording block. The call is made on that object, hence the test passes.

In the second test, you set an expectation on that same object, but the actually happens on the object created in the static method. Hence the difference. By adding the constructor line into the recording block, you make sure that you mock the next created object, which is in the static method.

Here's the final test code that works:
            
            [TestMethod]
            [VerifyMocks]
            public void MyType_Parsed()
            {
                
                using (RecordExpectations recorder = new RecordExpectations())
                {
                    MyType mockedType = new MyType();
                    recorder.ExpectAndReturn(mockedType.MyField, "abc").RepeatAlways();
                }

                MyType ReturnedType = MyType.Parse("xyz");
                Assert.AreEqual("abc", ReturnedType.MyField);
            }


Also, there's a short tutorial on this very subject here (lesson 4): https://www.typemock.com/Multimedia.html
answered by gilz (14.5k points)
0 votes
Of course! I see...

Thanks for the clarification and links to video.

Vagif
answered by vagif (19.4k points)
...