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
We are having a problem when we want to change the value of the WillReturn method. Here is a short example.

   public class ClassToIsolate {
      public int RetournerValeur () {
         return 42;
      }
   }
   
   class Program {
      static void Main (string [] args) {
         ClassToIsolate fake = Isolate.Fake.Instance<ClassToIsolate> ();
         Isolate.Swap.AllInstances<ClassToIsolate> ().With (fake);

         ClassToIsolate c = new ClassToIsolate ();
         Isolate.WhenCalled (() => fake.RetournerValeur ()).WillReturn (1);
         Console.WriteLine (c.RetournerValeur ());
         Console.WriteLine (c.RetournerValeur ());
         Console.WriteLine (c.RetournerValeur ());
   
         Console.WriteLine ();
         Isolate.WhenCalled (() => fake.RetournerValeur ()).WillReturn (2);
         Console.WriteLine (c.RetournerValeur ());
         Console.WriteLine (c.RetournerValeur ());
         Console.WriteLine (c.RetournerValeur ());

         Console.WriteLine ();
         Isolate.WhenCalled (() => fake.RetournerValeur ()).WillReturn (3);
         Console.WriteLine (c.RetournerValeur ());
         Console.WriteLine (c.RetournerValeur ());
         Console.WriteLine (c.RetournerValeur ());
      }
   }


Basically, we were hoping that it would return 1/1/1 2/2/2 3/3/3 but what we get is

1
1
1

1
2
2

2
3
3


That is, there is always one old value left, after we changed the value to be returned. We understand that if we set the WillReturn 3 time before any calls, and then call three times we will should get the 3 values. In the above case however, is this the intended behavior? It seems counter-intuitive.

Thanks for any light you can shed on this problem.
asked by sellingerd (5.7k points)

1 Answer

0 votes
Hi,

This is the intended behavior. WhenCalled() set a sequence behaviors, where the last behavior is the default one. WhenCalled() is intended to be used during the arrange step of the test. In the given example, the arrange and act steps are mixed.

Since this is not the first time users encounter this, I'll add a feature request for extending the API to support it. If you have suggestions on how it should be done (like API, behavior, etc.) you're welcome to post them.

Meanwhile you can use these two solutions:
1. If the number of expected calls is known during the arrange step, you can define a sequence in advance:
[TestMethod]
public void Test()
{
    var fake = Isolate.Fake.Instance<ClassToIsolate>();

    Isolate.WhenCalled(() => fake.RetournerValeur()).WillReturn(1);
    Isolate.WhenCalled(() => fake.RetournerValeur()).WillReturn(1);
    
    Isolate.WhenCalled(() => fake.RetournerValeur()).WillReturn(2);
    Isolate.WhenCalled(() => fake.RetournerValeur()).WillReturn(2);
    
    Isolate.WhenCalled(() => fake.RetournerValeur()).WillReturn(3);
    Isolate.WhenCalled(() => fake.RetournerValeur()).WillReturn(3);

    Assert.AreEqual(1, fake.RetournerValeur());
    Assert.AreEqual(1, fake.RetournerValeur());
    
    Assert.AreEqual(2, fake.RetournerValeur());
    Assert.AreEqual(2, fake.RetournerValeur());
    
    Assert.AreEqual(3, fake.RetournerValeur());
    Assert.AreEqual(3, fake.RetournerValeur());
}


2. If you want to set the value using state during act step, you can define dynamic behavior to the method using DoInstead():
[TestMethod]
public void Test()
{
    var fake = Isolate.Fake.Instance<ClassToIsolate>();
    int value = 0;
    Isolate.WhenCalled(() => fake.RetournerValeur()).DoInstead(context => value);

    value = 1;
    Assert.AreEqual(1, fake.RetournerValeur());
    Assert.AreEqual(1, fake.RetournerValeur());

    value = 2;
    Assert.AreEqual(2, fake.RetournerValeur());
    Assert.AreEqual(2, fake.RetournerValeur());

    value = 3;
    Assert.AreEqual(3, fake.RetournerValeur());
    Assert.AreEqual(3, fake.RetournerValeur());
}


Regards,
Elisha
Typemock Support Team
answered by Elisha (12k points)
...