Mocking static classes inside the testing method

4 posts, 0 answers
  1. David
    David avatar
    3 posts
    Member since:
    Feb 2015

    Posted 02 Feb 2015 Link to this post

    I have code that I want to test that looks similar to this:
    01.public class Manager
    02.{
    03.    public Job Job {get;set;}
    04. 
    05.    public void RunCompleteJob(int arg1, int arg2, int arg3, string arg4)
    06.    {
    07.         Job = MyStaticClass.CreateCompleteJob(arg1, arg2, arg3, arg4);
    08.         Job.Submit();
    09.         ExecuteJobStates();
    10.     }
    11.}

    I want to test this method, but I am getting stuck when I try to return an object when the static method is called.  Here is the test method:
    01.[Test]
    02.public void RunCompleteJob_Success()
    03.{
    04.    var arg1 = 2000999;
    05.    var arg2 = 12345;
    06.    var arg3 = 9999;
    07.    var arg4 = "filepath;
    08. 
    09.    var manager = Mock.Create<Manager>(Behavior.CallOriginal);
    10.    Mock.SetupStatic(typeof(MyStaticClass), Behavior.Strict, StaticConstructor.Mocked);
    11.    Mock.Arrange(() => MyStaticClass.CreateCompleteJob(arg1, arg2, arg3, arg4))
    12.        .Returns(new Job
    13.            {
    14.                JobProcessTypeParameters = new JobParameters(),
    15.                JobType = JobType.Complete,
    16.                MediaId = arg1
    17.            });
    18.    Mock.Arrange(() => manager.Job.Submit()).MustBeCalled();
    19.    Mock.NonPublic.Arrange(manager, "ExecuteJobStates").MustBeCalled();
    20. 
    21.    manager.RunCompleteJob(arg1, arg2, arg3, arg4);
    22. 
    23.    Mock.Assert(manager);
    24.    Assert.AreEqual(arg1, manager.Job.MediaId);
    25.}

    The last assert statement always returns an error saying that 2000999 does not equal 0.  Which implies that the Job property is not getting set the the new instance I am trying to return in the Arrange section.  

    What am I doing wrong?  Is this something that can't be done as it is written?  Please help, I am new to the JustMock framework.
  2. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 05 Feb 2015 Link to this post

    Hi David,

    The issue comes from the fact that you arrange the getter of the Job property, by applying the following:
    Mock.Arrange(() => manager.Job.Submit()).MustBeCalled();

    In order to prevent this, you will need to arrange the above against the returned object directly, as our auto mocking feature (recursive mocks) goes through the chain and applies non-null object return for the manager.Job property.

    Here is a possible approach for this:
    var arg1 = 2000999;
    var arg2 = 12345;
    var arg3 = 9999;
    var arg4 = "filepath";
     
    var manager = Mock.Create<Manager>(Behavior.CallOriginal);
    Mock.SetupStatic(typeof(MyStaticClass), Behavior.Strict, StaticConstructor.Mocked);
    var job = new Job
            {
                JobProcessTypeParameters = new JobParameters(),
                JobType = JobType.Complete,
                MediaId = arg1
            };
    Mock.Arrange(() => MyStaticClass.CreateCompleteJob(arg1, arg2, arg3, arg4))
        .Returns(job);
    Mock.Arrange(() => job.Submit()).MustBeCalled();
    Mock.NonPublic.Arrange(manager, "ExecuteJobStates").MustBeCalled();
     
    manager.RunCompleteJob(arg1, arg2, arg3, arg4);
     
    Mock.Assert(manager);
    Mock.Assert(job);
    Assert.AreEqual(arg1, manager.Job1.MediaId);

    Here, we create a Job object, that later on will be returned for the CreateCompleteJob call. Having this, we can directly arrange and assert against that object.

    Further, we are aware that there are cases where this is not very intuitive (just as yours), so we definitely consider improvements for future JustMock releases.

    I hope this helps.

    Regards,
    Kaloyan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. DevCraft R3 2016 release webinar banner
  4. David
    David avatar
    3 posts
    Member since:
    Feb 2015

    Posted 05 Feb 2015 in reply to Kaloyan Link to this post

    Thank you!  I will give it a try.

    Quick question...  In trying to understand the mocked objects.  In the call you make above
    Mock.Arrange(() => job.Submit()).MustBeCalled();
    Is this going to call the real Submit() code or the mocked up Submit() code?

    Since you didn't call Mock.Create() I would assume this is actually going to call the real code.  Is that correct?
  5. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 10 Feb 2015 Link to this post

    Hello David,

    Yes, that's correct. Arranging objects that were not created using Mock.Create is called "partial mocking". Partial mocks work the same as full mocks with Behavior.CallOriginal.

    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top