Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

'object' Does Not Contain a Definition for 'errors'

DZone's Guide to

'object' Does Not Contain a Definition for 'errors'

·
Free Resource

Today I ran into an interesting issues when writing a unit test for an ExceptionFilter which involved inspecting anonymous return types.

I basically had the requirement to return a Json object with a predefined structure (for our ASP.net WebApi endpoints) in case of exceptions resulting out of failed entity validations. So I started to write a unit test in my Api.UnitTests.csproj project which had a reference to Api.csproj where the actual implementation of the exception filter was. Here’s the skeleton of the exception filter:

public class EntityValidationExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
}
}

One of the unit tests looks like this:

[TestMethod]
public void ShouldReturnEntityValidationResultsAsAListOfErrorsInJson()
{
//arrange
var httpExecutedContext = CreateHttpActionExecutedContext(new EntityValidationException(
"Validation of Person failed",
new List<EntityValidationResult>()
{
new EntityValidationResult(new EntityEntry(null, System.Data.EntityState.Modified), new List<ValidationError>() {
new ValidationError("Firstname", "Firstname is required"),
new ValidationError("Surname", "Surname is required")
})
}));
//act
new EntityValidationExceptionFilter().OnException(httpExecutedContext);
//assert
var objContent = ((ObjectContent)httpExecutedContext.Response.Content);
dynamic content = objContent.Value;
Assert.IsNotNull(content.errors);
Assert.AreEqual(2, content.errors.Count);
}

There’s nothing special here, and if you read my post about ASP.net MVC Action Methods: Testing against anonymous return types then you should also not be surprised about the usage of dynamic.

Running the test makes it obviously fail. So let’s complete the implementation:

public class EntityValidationExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
if(actionExecutedContext.Exception is EntityValidationException)
{
//snip snip...some logic
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse((HttpStatusCode)422, new { errors = validationErrors });
}
else
{
base.OnException(actionExecutedContext);
}
}
}

Re-executing the test shoukld make it pass now…no, it doesn’t..why?? The exception I get:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'errors'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
...

I started to debug the test and inspected it in the Visual Studio debugger, and look there, the expected object shows up just fine, but any execution results in the above mentioned exception..(?!)

Inspecting in the debugger shows the expected object

Ahhh wait…I’m returning an anonymous type from my exception filter..will that be visible outside my tested DLL “Api”, probably not. Adding

[assembly:InternalsVisibleTo("Api.UnitTests")]

..into the AssemblyInfo.cs of Api.csproj and executing the test again proved my assumption: PASS.

Topics:

Published at DZone with permission of Juri Strumpflohner. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}