.net - How to test deserialization in ASP.NET Web API -
what's right way write unit test deserializing json object in web api?
in application noticed looking @ trace information web api trying deserialize object parameter comes request body calling jsonmeadiatypeformatter.readfromasync. i'm trying isolate problem wrote these test. readtestitem fails. other example readint passes, seems i'm on right track i'm not sure if web api doing.
edit: code fixed , formatterconfig added
class testclass { public string type { get; set; } public string value { get; set; } } [testclass] public class formattertest { [testmethod] public void readtestitem() { mediatypeformattercollection formatters = new mediatypeformattercollection(); formatterconfig.registerglobalformatters(formatters); jsonmediatypeformatter formatter = formatters[0] jsonmediatypeformatter; stream s = generatestreamfromstring("{ type: \"equal\", value: \"1\" }"); var content = new streamcontent(s); var logger = new mock<iformatterlogger>().object; var task = formatter.readfromstreamasync(typeof(testclass), s, content, logger); testclass result = task.result testclass; assert.areequal("equal", result.type); assert.areequal("1", result.value); } [testmethod] public void testreadint() { mediatypeformattercollection formatters = new mediatypeformattercollection(); formatterconfig.registerglobalformatters(formatters); jsonmediatypeformatter formatter = formatters[0] jsonmediatypeformatter; stream s = generatestreamfromstring("2"); var content = new streamcontent(s); var logger = new mock<iformatterlogger>().object; var task = formatter.readfromstreamasync(typeof(int), s, content, logger); assert.areequal(2, task.result); } public stream generatestreamfromstring(string s) { memorystream stream = new memorystream(); streamwriter writer = new streamwriter(stream); writer.write(s); writer.flush(); stream.position = 0; return stream; } }
here's formatter configuration:
public class formatterconfig { public static void registerglobalformatters(mediatypeformattercollection formatters) { var jsonserializersettings = formatters.jsonformatter.serializersettings; jsonserializersettings.converters.add(new isodatetimeconverter()); // serialize every enum string jsonserializersettings.converters.add(new newtonsoft.json.converters.stringenumconverter()); // include null value fields jsonserializersettings.nullvaluehandling = nullvaluehandling.ignore; // use camel case jsonserializersettings.contractresolver = new camelcasepropertynamescontractresolver(); // indented formatting bool indent; boolean.tryparse(configurationmanager.appsettings["dex.indentjson"], out indent); formatters.jsonformatter.indent = indent; formatters.remove(formatters.xmlformatter); } }
the approach looks fine me. you're correct in noticing readfromstreamasync gets called on request body. there's 2 strange things going on:
- the type pass in first test filteritemdto. expect result testclass? whatever type pass in formatter type should expect have deserialized. intending pass in testclass readfromstreamasync instead?
testclass has members type , value, json.net expect members "type" , "value in json, not "type" , "value". casing matters. there easy way camel casing line of code:
config.formatters.jsonformatter.serializersettings.contractresolver = new camelcasepropertynamescontractresolver();
Comments
Post a Comment