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

Mocking a Base Class Property

6 Answers 560 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Kalyan
Top achievements
Rank 1
Kalyan asked on 14 Feb 2017, 05:03 AM

Hello,

I'm new to JustMock and have been playing with it only for a few hours.  I have been able to convert a few of my existing tests from Microsoft Fakes to JustMock.  However, there's one test, where I'm having a lot of trouble and I'm hoping someone can help me with it.

 

I have a class that derives from the System.Web.Http.ApiController and here is a snapshot of it:

public class MyApiController : ApiController {
    public HttpResponseMessage Post(EPAQuestionsetLookupRequest lookup) {
        try {
            if (!ModelState.IsValid) {
                return new HttpResponseMessage(HttpStatusCode.NotAcceptable);
            }
            return new HttpResponseMessage(HttpStatusCode.OK);
        } catch {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }
    }
}

 

I have a test written as the follows:

[TestMethod]
public void PostNotValidState() {
    var controller = Mock.Create<MyApiController>();
    Mock.Arrange(() => controller.ModelState.IsValid).Returns(false).MustBeCalled();
    // Mock.Arrange(() => ((ApiController)controller).ModelState.IsValid).Returns(false).MustBeCalled();
    var response = controller.Post(lookup);
 
    Assert.AreEqual(HttpStatusCode.NotAcceptable, response.StatusCode);
    Mock.Assert(controller);
}

 

I've tried it in the above way and also using a Container instead.  But, in both cases, it seems like the ModelState.IsValid is continuing to return true (or the method during the test, is actually not using the arrangement I have, which is confirmed by the fact that the Mock.Assert is failing on the MustBeCalled) and is failing my test.  What's the best way for me to be able to mock the ModelState.IsValid to return false and for it to be honored?

6 Answers, 1 is accepted

Sort by
0
Svetlozar
Telerik team
answered on 16 Feb 2017, 03:53 PM
Hello,

Thank you for your great question. Mocks have behaviors. If you don't specify the behavior when you create the mock the default is RecursiveLoose which creates empty implementations for all members in the mocked instance. It is quite handy if you want to replace implementations, because you cut ties with all dependencies. What happens here is that you don't call your Post method, but the mocked Post method, which returns the default value.

When you want to call the original implementation you have to set the behavior to CallOriginal.

Here is the sample

[TestMethod]
public void TestMethod1()
{
    var controller = Mock.Create<MyApiController>(Behavior.CallOriginal);
    Mock.Arrange(() => controller.ModelState.IsValid).Returns(false).MustBeCalled();
    var lookup = new EPAQuestionsetLookupRequest();
    var response = controller.Post(lookup);
 
    Assert.AreEqual(HttpStatusCode.NotAcceptable, response.StatusCode);
    Mock.Assert(controller);
}

I hope that helps. Let me know if you have any questions. 

Regards,
Svetlozar
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Kalyan
Top achievements
Rank 1
answered on 16 Feb 2017, 07:30 PM

Thank you very much.  That did it.

After that worked, I was trying the same kind of test using the Mocking Container and I still see it not mocking the response on the IsValid call.  Here is my code:

 

var container = new MockingContainer<MyApiController>(new AutoMockSettings { MockBehavior = Behavior.CallOriginal });
 
container.Arrange<System.Web.Http.ModelBinding.ModelStateDictionary>(ModelState => ModelState.IsValid).Returns(false).MustBeCalled();
var response = container.Instance.Post(lookup);
Assert.AreEqual(HttpStatusCode.NotAcceptable, response.StatusCode);
container.Assert();

 

Greatly appreciate, if you can point out what I'm messing up here.

 

Thanks,

Kalyan

0
Kalyan
Top achievements
Rank 1
answered on 16 Feb 2017, 08:01 PM

This definitely seems to work.  But, I'm still a little confused.  Without the CallOriginal behavior, when I debug, it still takes me into the implementation of my Post method and I'm able to step through the code.  So, if it is not using the original implementation, why is it stepping through my implementation?  I'm definitely confused.

 

Thanks,

Kalyan

0
Svetlozar
Telerik team
answered on 21 Feb 2017, 08:31 AM
Hello,

I am really sorry for the misunderstanding. The debugger follows the information from the pdb file. That is the file that has the source code -> IL map that is used for debugging. Since we rewrite the IL code at runtime we also try to rewrite the pdb stream to point to the generated code, but there are still some cases where we fall short to do so. I hope that makes sense. 

Regards,
Svetlozar
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Kalyan
Top achievements
Rank 1
answered on 22 Feb 2017, 03:34 AM

OK.  I understand.  Will appreciate if you can help me understand what's going on with the way I'm using the Mocking Container to solve this exact scenario.  The post is in one of the comments above: http://www.telerik.com/forums/mocking-a-base-class-property#6UyLeSO4WUeZU0Wt3IafdQ

 

Thanks,

Kalyan

0
Svetlozar
Telerik team
answered on 23 Feb 2017, 04:59 PM
Hi,

I am sorry for the misunderstanding. 

Automocking works with Ninject under the hood. You can't mock arbitrary properties with it. I suggest you continue with the standard way of mocking your dependencies. 

Regards,
Svetlozar
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
General Discussions
Asked by
Kalyan
Top achievements
Rank 1
Answers by
Svetlozar
Telerik team
Kalyan
Top achievements
Rank 1
Share this question
or