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
I found that if one of the arguments of a constructor throws an exception, then the Mock simply can't work. Here's my class code
   public class FreeForm
   {
      private int sim=0;
      private PreFreeForm pff;
      public FreeForm(PreFreeForm pffmy)
      {
         pff = pffmy;
      }
      public FreeForm(int smte)
      {
   //      pff = pffMy;
         sim = smte;
         pff.Count=10;
      }
   }



   internal class PreFreeForm
   {
      private int count =0;
      public int Count
      {
         get { return count; }
         set { count = value; }
      }
      public PreFreeForm(int cc)
      {
         count = cc;
      }
   }


   public class SimpleClass
   {
      private FreeForm myff;
      private PreFreeForm prff;
       public static string mName = "TypeMock";
      public string ANumber
      {
         get{return mName;}
      }
      public SimpleClass()
      {
   //      astring.IndexOf("Aline");
         myff = new FreeForm(prff.Count);

      }
   }


Here is the test code
      [Test, VerifyMocks]
      public void MockInternal()
      {
         Mock mo = MockManager.MockAll(typeof(SimpleClass));
         SimpleClass sc = new SimpleClass();
      }


This is the exception I got:
------ Test started: Assembly: ClassLibrary1.dll ------

TestCase 'ClassLibrary1.Class1.MockInternal'
failed: System.NullReferenceException : Object reference not set to an instance of an object.
c:documents and settingssoon hui.esteemsoftmy documentsjobs hird party components ypemockaseclasssimpleclass.cs(17,0): at BaseClass.SimpleClass..ctor()
c:documents and settingssoon hui.esteemsoftmy documentsjobs hird party components ypemockclasslibrary1 estclass.cs(162,0): at ClassLibrary1.Class1.MockInternal()
at TypeMock.MethodDecorator.CallRealMethod()
at TypeMock.DecoratorAttribute.CallDecoratedMethod()
at TypeMock.VerifyMocksAttribute.Execute()
at TypeMock.DecoratorAttribute.CallDecoratedMethod()
at TypeMock.ClearMocksAttribute.Execute()
at TypeMock.MethodDecorator.d()
at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5)
at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected)
c:documents and settingssoon hui.esteemsoftmy documentsjobs hird party components ypemockclasslibrary1 estclass.cs(158,0): at ClassLibrary1.Class1.MockInternal()


0 passed, 1 failed, 0 skipped, took 1.17 seconds.

Since I want to mock away the constructor for FreeForm, it shouldn't really matter what I pass into the constructor, even though one of the argument of it will return an exception when called, right?:)

If this is not a bug, you may want to suggest a workaround method so that I can mock the above successfully.
________
A100
asked by nsoonhui (59.1k points)

11 Answers

0 votes
Hi,

You are correct, and this should not happen, since the SimpleClass constructor should be mocked, it is a bug. However, we cannot reproduce it here.

I'll send you a separate mail, regarding retrieving logs and traces. We'll see what we can make of it.
answered by gilz (14.5k points)
0 votes
Sorry, I didn't specify the test case properly. The test case should be:
      [Test, VerifyMocks]
      public void MockInternal()
      {
   //      Mock mo = MockManager.MockAll(typeof(SimpleClass));
         Type ty = Assembly.GetExecutingAssembly().GetType("ClassLibrary1.FreeForm");
         Mock mo = MockManager.MockAll(ty);
         SimpleClass sc = new SimpleClass();
      } 


My intention was to mock away the constructor for FreeForm, but since a parameter to FreeForm constructor threw an exception, Typemock reported an exception to me, even though it shouldn't. Typemock should allow me to mock FreeForm constructor successfully.
________
buy marijuana seeds
answered by nsoonhui (59.1k points)
0 votes
Hi
This should still work. We will check it out and let you know.
:!: However if your intention is to mock only the calls to the FreeFrom class. You shouldnt mock the SimpleClass.
answered by lior (13.2k points)
0 votes
Hi
This should still work. We will check it out and let you know.
:!: However if your intention is to mock only the calls to the FreeFrom class. You shouldnt mock the SimpleClass.


Thank you for the information. Would like to hear further from you.
________
CR125R
answered by nsoonhui (59.1k points)
0 votes
Hi
This should still work. We will check it out and let you know.
:!: However if your intention is to mock only the calls to the FreeFrom class. You shouldnt mock the SimpleClass.


Hi, just want to check on the status for this case? How is it going on?

regards
________
DR-Z400S
answered by nsoonhui (59.1k points)
0 votes
Hi
The problem is that when you mock the FreeForm class
the call to the constructor is executed but the code in the body of the constructor is not executed.
So what happens is that the line:
myff = new FreeForm(prff.Count);

Fails because prff is null.

Let me know if you need more help with this issue :)
answered by ohad (35.4k points)
0 votes
Hi
The problem is that when you mock the FreeForm class
the call to the constructor is executed but the code in the body of the constructor is not executed.
So what happens is that the line:
myff = new FreeForm(prff.Count);

Fails because prff is null.

Let me know if you need more help with this issue :)


Thanks ohad, but I thought that the prff.Count should be mocked also since I don't want to call the FreeForm constructor ?
________
penny stocks to watch
answered by nsoonhui (59.1k points)
0 votes
Hi,
Actually no,
prff.Count is a different call on a different class altogether.
because the clr activate this method BEFORE the call to the FreeForm constructor. There is no way to know about this.

from our framework point of view
myff = new FreeForm(prff.Count);

is equivalent to:
int data = prff.Count;
myff = new FreeForm(data);


In any case, alto ugh this is a simplified example, I do think that the test you have written actually exposes a real flaw. looking at the "code" the prff member is never initialized.

:idea: Actually Natural Mocks is much in the spirit of your way of thinking. how about giving it a try?
answered by lior (13.2k points)
0 votes
Hi,
Actually no,
prff.Count is a different call on a different class altogether.
because the clr activate this method BEFORE the call to the FreeForm constructor. There is no way to know about this.

from our framework point of view
myff = new FreeForm(prff.Count);

is equivalent to:
int data = prff.Count;
myff = new FreeForm(data);


In any case, alto ugh this is a simplified example, I do think that the test you have written actually exposes a real flaw. looking at the "code" the prff member is never initialized.



Actually what happens is this: I want to mock away FreeForm because I just want to test SimpleClass. I don't want to get bog down in constructing the FreForm objects (Which is difficult to construct anyway and may involve a lot of object construction of other types). During the unit test time, I don't want to initialize the prff, that is intentional. So I hope that TypeMock can do the job for me even though I don't specify it directly.

Any idea on how to handle this case?


:idea: Actually Natural Mocks is much in the spirit of your way of thinking. how about giving it a try?

f you notice, actually I am using Natural Mocks already in my example.[/quote]
________
F-4EAT transmission
answered by nsoonhui (59.1k points)
0 votes
Hi,

Anyway, I'm not really sure I understand what you're actual intention. for me it looks as if I'm looking at half the implementation. you are trying to test SimpleClass which is dependent on TWO other type:
* FreeForm which is created in the constructor
* PreFreeForm which is the prff field (does does not get initialized anywhere).

If everything was in place our actual test should have looked like:
[Test, VerifyMocks]
public void MockInternal()
{
    Mock moprff = MockManager.MockAll(typeof(PreFreeForm));
    moprff.ExpectGetAlways("Count", 7);
    Mock mo = MockManager.MockAll(typeof(FreeForm));
    SimpleClass sc = new SimpleClass();

}


However for this to work the instance field prff MUST be initialized somewhere. If its not done, the CLR will throw a NullReferanceException the minute it encounters the prff.Count statement no matter what is mocked.

:!: in our next release we will include an API for Mocking Fields that as far as i can tell will be extremely useful in this situation. if you like i will add you to our beta users list.
answered by lior (13.2k points)
...