This is a migrated thread and some comments may be shown as answers.

Mocking static classes inside the testing method

3 Answers 313 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
David
Top achievements
Rank 1
David asked on 03 Feb 2015, 12:06 AM
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.

3 Answers, 1 is accepted

Sort by
0
Kaloyan
Telerik team
answered on 05 Feb 2015, 11:42 AM
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.

 
0
David
Top achievements
Rank 1
answered on 05 Feb 2015, 06:39 PM
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?
0
Stefan
Telerik team
answered on 10 Feb 2015, 10:22 AM
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.

 
Tags
General Discussions
Asked by
David
Top achievements
Rank 1
Answers by
Kaloyan
Telerik team
David
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or