dimanche 6 décembre 2015

LINQ to Entities error occurring at run time but not in unit test

I am unit testing a method in one of my controllers to check that correct data is being returned with a Linq query (this may be an integration test, but the question still stands).

I am trying to follow TTD as much as possible by replicating any errors I get at run time in a test before fixing it in the code.

However, I am running into an error that only occurs during run-time execution of my application not during my test.

The exception I get during run-time is:

Exception thrown: 'System.NotSupportedException' in Newtonsoft.Json.dll

Additional information: LINQ to Entities does not recognize the method 'System.String ToLowerInvariant()' method, and this method cannot be translated into a store expression.

The method under test is:

[HttpGet]
public ActionResult GetRegions(string term)
{
    var regions = from region in DbContext.Culture
                  where
                      !region.NeutralCultureFlag &&
                      (term == null || (region.NativeName + region.CultureCode).ToLowerInvariant().Contains(term.ToLowerInvariant()))
                  orderby region.Name
                  select region;

    return Json(regions.Select(x => new
                {
                    id = x.CultureId,
                    text = x.NativeName + " (" + x.CultureCode + ")"
                })
    );
}

The fix for the error is clearly to change (region.NativeName + region.CultureCode).ToLowerInvariant() to (region.NativeName.ToLowerInvariant() + region.CultureCode.ToLowerInvariant()) but I would like to get this error in my test before I fix it.

My test method is:

public void Test1(string term, int expectedCount)
{
    var result = _controller.GetRegions(term);

    Assert.IsType(typeof (JsonNetResult), result);
    var jsonResult = (JsonNetResult)result;

    var data = GetJsonObject<List<JsonData>>(jsonResult);
}

JsonNetResult is a custom class that extends the normal JsonResult so I can use Json.Net instead of the standard Json serialiser.

The ExecuteResult method in JsonNetResult looks like:

public override void ExecuteResult(ControllerContext context)
{
    if (context == null)
        throw new ArgumentNullException("context");

    HttpResponseBase response = context.HttpContext.Response;
    response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;

    if (this.ContentEncoding != null)
        response.ContentEncoding = this.ContentEncoding;
    if (this.Data == null)
        return;

    var scriptSerializer = JsonSerializer.Create(this.Settings);

    using (var sw = new StringWriter())
    {
        scriptSerializer.Serialize(sw, this.Data); //error occurs here
        response.Write(sw.ToString());
    }
}

The exception occurs at scriptSerializer.Serialize(sw, this.Data);.

Is there a way to replicate the error in my unit test so I can be sure it is fixed properly following TTD principles?

Aucun commentaire:

Enregistrer un commentaire