14

I have this code in C# mvc Controller:

[HttpPost]
    public ActionResult Delete(string runId)
    {
        if (runId == "" || runId == null)
        {
            return this.Json(new { error = "Null or empty params" });
        }
        try
        {
            int userId = (int)Session["UserId"];
            int run = Convert.ToInt32(runId);

            CloudMgr cloud = new CloudMgr(Session);
            cloud.DeleteRun(userId, run);

            return this.Json(new { success = true });
        }
        catch (Exception ex)
        {
            return this.Json(new { error = ex.ToString() });
        }
    }

How I can access my Json "error" field in a ControllerTest to check if it is null or not?

[TestMethod]
    public void DeleteWrongParam()
    {
        WhatIfController controller = new WhatIfController();
        controller.ControllerContext = 
        TestUtils.CreateMockSessionControllerContext().Object as ControllerContext;

        JsonResult result = controller.DeleteWhatIf(null) as JsonResult;

Assert.IsNotNull(result.Data.error); is what I would like to do. Any Ideas? Thanks.

3 Answers 3

27

JavaScriptSerializer is good for string and static type. Here you created anonymous type as Json(new { success = true }). This case, you had better used dynamic type.

JsonResult result = controller.DeleteWhatIf(null) as JsonResult;
dynamic dresult = result.Data;
Assert.IsTrue(dresult.succes);

You need to import Microsoft.CSharp dll to test project.

If test and your controller are in different assemblies, you need to make the test assembly a "friend" assembly of the controller assembly, like this:

[assembly: InternalsVisibleTo("testproject assembly name")]

Sign up to request clarification or add additional context in comments.

5 Comments

+1 for the InternalsVisibleTo tip. I tried doing this without having that assembly attribute it place and couldn't figure out why it was blowing up at first.
Seconded. I've edited the answer to draw attention to the part about InternalsVisibleTo.
you can make it more easier dynamic result = controller.DeleteWhatIf(null) as JsonResult; Assert.IsNotNull(result.Data.error); =)
it raises an exception: 'object' does not contain a 'success' definition.... any idea? thanks
Given the exception I'm getting, I'm surprised this worked for anyone. Today, I am seeing the following; LandingControllerTests.WhenCalledWithinAValidEnvironment_IndexGetMethod_ShouldReturnExpectedData threw exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'model' at CallSite.Target(Closure , CallSite , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at VotingSite.Tests.Controllers.LandingControllerTests.<WhenCalledWithinAValidEnvironment_IndexGetMethod_ShouldReturnExpectedData>...
21

You can use like this - the result will be the expected object definition. So in case of success, your success flag will be TRUE otherwise false and if false then you should expect that the error property will be updated with the error message.

        JsonResult jsonResult = oemController.List() as JsonResult;
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        Result result = serializer.Deserialize<Result>(serializer.Serialize(jsonResult.Data));

        public class Result 
        {
            public bool success ;
            public string error;
        }

4 Comments

What is the namespace for Result class? Thanks.
@juanchoelx Result is your own defined class like this class Result { public bool success ; public string error }
With this solution you need as many "Result" classes as different JSon results you have. If you build a new Action which returns two integers instead of success/error fields, you need to build a new class.
that's incredibly inefficient
-2

If you returned an actually non-anonymous class, you could have just done:

var strongTypedResult = result as <YourStrongTypeHere>;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.