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
So I got past the legacy crap we can't control with 'ref' (https://www.typemock.com/community/viewtopic.php?t=1198) using the advise there.

But now I'm having to deal with out parameters and this technique doesn't seem to work. Just substitute what is in that other thread with 'out' instead of 'ref' and you have the situation I'm dealing with.

A difference is this legacy thing I'm touching also has ref parameters and a return value and I'm noticing that the ref values aren't being set either this time.

How do I test this?

Here's the signature of the method I want to fake and have the output parameters/ref parameters set for:

bool LegacyMethod(string, string, string, string, int, string, string DateTime?, SomeType1, DateTime?, SomeType2, SomeType3, ref long, string, out int, out string, out SomeType4)

The out someType4 is what I'm mainly concerned about.
asked by boo (21.8k points)

3 Answers

0 votes
Brian,

I ran a few tests here with the out equivalent of the ref, in the AAA, according to the first post. It works here.

Can you check again, and if it doesn't work, can you post a repro?
Thanks,
answered by gilz (14.5k points)
0 votes
Here's the repro code to test against:

   public class SomeClassThatUsesLegacyClass
   {
      public static void CallTheLegacyMethod()
      {
         LegacyClass legacy = new LegacyClass();

         //These nomrally come from properties in the class
         string id = "XYZ";
         int? someNumberAsNullable = 5;
         DateTime date1 = DateTime.Today;

         //These are output variables set by legacy method
         string someOutName1;
         int? someOutNumber1;
         long? someOutNumber2;
         MessageClass messages;

         bool result = legacy.LegacyDeleteMethod(id, someNumberAsNullable, date1, false, "DELETED FROM APP1", out someOutName1, out someOutNumber1, out someOutNumber2, out messages);
         if (!result)
         {
            if (messages != null)
            {
               throw new Exception("An exception occurred: " + messages.SomeMessage2);
            }
            else
            {
               throw new Exception("Legacy method was not successful but didn't tell us why.");
            }
         }
      }
   }


   public class MessageClass
   {
      public string SomeMessage1 { get; set; }
      public string SomeMessage2 { get; set; }
      public string SomeMessage3 { get; set; }
      public string SomeMessage4 { get; set; }
   }

   public class LegacyClass
   {
      public bool LegacyDeleteMethod(string SOME_ID, System.Nullable<int> SOME_NUMBER, System.DateTime SOME_DATE1, bool ARCHIVE, string COMMENT, out string SOME_NAME, out System.Nullable<int> SOME_OTHER_NUMBER, out System.Nullable<long> SOME_OTHER_ID, out MessageClass Exception)
      {
         throw new NotImplementedException("Real code would go here");
      }
   }



Here's the test that fails...if you walk through you'll see we're going into the 'else' because the out parameter is null.
      [Isolated(), TestMethod()]
      public void TestMethod1()
      {
         //Arrange
         MessageClass message = new MessageClass()
         {
            SomeMessage1 = "TEST1",
            SomeMessage2 = "TEST2",
            SomeMessage3 = "TEST3",
            SomeMessage4 = "TEST4"
         };

         int? someNumberAsNullable = 5;
         DateTime date1 = DateTime.Today;
         string someOutName1;
         int? someOutNumber1;
         long? someOutNumber2;

         LegacyClass legacyFake = Isolate.Fake.Instance<LegacyClass>();
         Isolate.WhenCalled(() => legacyFake.LegacyDeleteMethod("", someNumberAsNullable, date1, false, "", out someOutName1, out someOutNumber1, out someOutNumber2, out message));
         Isolate.Swap.NextInstance<LegacyClass>().With(legacyFake);

         //Act
         try
         {
            SomeClassThatUsesLegacyClass.CallTheLegacyMethod();
            Assert.Fail("Expected message");
         }
         catch(Exception ex)
         {
            //Assert
            Assert.IsTrue(ex.Message.Contains(message.SomeMessage2));
         }
      }
answered by boo (21.8k points)
0 votes
Hi Brian

We have a bug in setting ref and out parameters when using Members.ReturnRecursiveFakes (This is the default for Isolate.Fake.Instance<>() method)

As a workaround you can change the test code like this:
LegacyClass legacyFake = Isolate.Fake.Instance<LegacyClass>(Members.ReturnNulls);


This will make the test pass.
answered by ohad (35.4k points)
...