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.

J punto Marcos
  • 437
  • 1
  • 6
  • 24
juanchoelx
  • 387
  • 1
  • 6
  • 20

3 Answers3

25

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")]

Gary McGill
  • 26,400
  • 25
  • 118
  • 202
ttacompu
  • 873
  • 1
  • 10
  • 15
  • +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. – Landon Poch Feb 28 '14 at 17:30
  • Seconded. I've edited the answer to draw attention to the part about `InternalsVisibleTo`. – Gary McGill Sep 11 '15 at 13:15
  • 2
    you can make it more easier `dynamic result = controller.DeleteWhatIf(null) as JsonResult; Assert.IsNotNull(result.Data.error);` =) – RustemMazitov Jun 07 '16 at 12:17
  • 3
    it raises an exception: 'object' does not contain a 'success' definition.... any idea? thanks – Thiago Melo Jan 26 '17 at 13:18
  • 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....` – Scott Fraley Jun 27 '19 at 16:14
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;
        }
RickL
  • 3,318
  • 10
  • 38
  • 39
Devesh
  • 4,500
  • 1
  • 17
  • 28
-2

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

var strongTypedResult = result as <YourStrongTypeHere>;

hyankov
  • 4,049
  • 1
  • 29
  • 46