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
When using reflective mocks. If we have a method or property that returns a nullable type and we return null in as a DynamicReturnValue, typemock throws an exception. It should not.

Here is an example program that illustrates the problem:

using System;
using TypeMock;

namespace BugDynamicReturnValue {
   class Program {
      static void Main (string [] args) {
         Mock<Stockage> stockageMock = MockManager.Mock<Stockage> ( );
         stockageMock.ExpectGet ("Prop", new DynamicReturnValue (
            delegate (Object [] parameters, Object context) {
               return null;
            }
         ));

         Stockage stock = new Stockage ();

         if (stock.Prop.HasValue) {
            Console.WriteLine (stock.Prop.Value);
         } else {
            Console.WriteLine ("Null");
         }
      }

      class Stockage {

         public bool? Prop {
            get {
               return null;
            }
         }
      }
   }
}


When we run this program, typemock (5.3.0) throws the following exception:

Exception non gérée : TypeMock.TypeMockException:
*** Cannot return Null value from method that returns System.Nullable`1[System.Boolean]
à w.a(Object A_0, Type A_1)
à w.a(Object A_0, Object[] A_1, Type A_2, Scope A_3, Int32 A_4, Object A_5, Type A_6)
à ca.a(String A_0, Object[] A_1, Object A_2, Object A_3, String A_4, Type A_5)
à TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5)
à TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected)
à BugDynamicReturnValue.Program.Stockage.get_Prop() dans C:\dev\vigis\tools\BugDynamicReturnValue\Example\Program.cs:ligne 26
à BugDynamicReturnValue.Program.Main(String[] args) dans C:\dev\vigis\tools\BugDynamicReturnValue\Example\Program.cs:ligne 16



If we comment out the mock, the real function can return null without a problem.

How should we be mocking nullable types?
asked by sellingerd (5.7k points)

7 Answers

0 votes
Hi
I checked it out and you are right, indeed we have a bug in reflective mock API :evil:

However I can offer you two workarounds:
The best solution is to use our new Arrange Act Assert API
Here is an example of the same test with AAA API:
[TestMethod]
public void NullableDoInstead()
{
    var fake = Isolate.Fake.Instance<Stockage>();
    // this  line replaces the DynamicReturnValue in the reflective mocks API
    Isolate.WhenCalled(() => fake.Prop).DoInstead(context => { return null; });
    Isolate.Swap.NextInstance<Stockage>().With(fake);

    Stockage stock = new Stockage();

    bool? result = stock.Method();
    Assert.IsNull(result);
}


If for some reason you can't use the AAA API, here is an example using natural mocks API:
[TestMethod]
public void NullableNaturalMocks()
{
    using (var rec = RecorderManager.StartRecording())
    {
        Stockage mock = new Stockage();
        var dum = mock.Prop;
        
        rec.Return(new DynamicReturnValue(
                   delegate(Object[] parameters, Object context)
                   {
                       return null;
                   }
                   ));


    }

    Stockage stock = new Stockage();
    Assert.IsNull(stock.Method());
}


Hope it helps.
answered by ohad (35.5k points)
0 votes
Yes, unfortunately, we have some expertise in the reflective API (as well as a large number of tests implemented using it). Will this bug be fixed soon?
answered by sellingerd (5.7k points)
0 votes
The Reflective API is considered "legacy" API and we are moving forward with the AAA API only.
That means that for the time being only critical bugs with no workaround will be fixed in APIs that are older (reflective as well as natural\record\replay APIs are considered as such)

This bug does have a workaround, so we are actively putting efforts only into the API that we now recommend our customers to use - the new AAA API for C#\VB.NET.

The new API is much simpler, elegant and easier to learn, and has more advanced and elegant abilities than the older API.
The new API is easy to spot - for C# it *always* starts with the work "Isolate."
answered by royo (2k points)
0 votes
The reflective API is not marked as obsolete in your documentation. Since we have purchased typemock two or three years ago, you have implemented two completely different API's, "natural mocks" and AAA.

Given that we have a significant investment in reflective mocks and the rather sparse documentation for the new API's, especially when they are first released, I am reluctant to switch APIs lightly. It appears that this was a good choice for natural mocks as it is now also on the endangered species list .

It is a significant effort to retrain everyone to a completely new mock API every couple of years (even if it is better) and then decide what we have to do with our tests when they are broken, that is, should I rewrite the other reflective mock tests or should we just avoid using typemock?

I think if your API is not marked as obsolete, we should at least have bug fixes.
answered by sellingerd (5.7k points)
0 votes
Hi

I can understand your reluctance, but I believe that the AAA API is far easier and simpler to learn, and I'll be happy to arrange a live session for you and your team to help you migrate to the new API.

Unfortunately, we only issue bug patches for older versions (or older API, in this case), for maintenance subscribers.
answered by ohad (35.5k points)
0 votes
I am currently a maintenance subscriber (expires in 12 days).
answered by sellingerd (5.7k points)
0 votes
Hi
I apologize for the misunderstanding.
I'll send you a patch.
answered by ohad (35.5k points)
...