1

Unit Testing & dynamics noob here...

I realize this is not the best way to parse JSON. I'm just trying to wrap my brain around dynamics and how to add tests for them.

I was working with JSON parsing with the help of this anwser from this question about JSON Deserialization into a C# dynamic object.

Here is an example JSON string:

string jsonText = "{ name: \"Google\", uri: \"http://www.google.com\" }";

Let's say I have a class called Site that has a name and uri property and I want to instantiate it with dynamic data that I deserialized from the JSON string above:

dynamic data = jss.Deserialize(jsonText, typeof(object)) as dynamic;

var account = new Site{
    name = data.sid,
    uri = data.uri
};

This will throw a runtime binder exception on 'string' to 'System.Uri'.

I thought this is a great opportunity to learn about unit testing (been wanting to for a while). I'd write this test, confirm the failure, then make it work. Here is the test:

[TestMethod()]
public void UriDynamicTest()
{
    Site target = new Site();
    dynamic uri = "http://www.google.com";
    var expected = uri;
    Uri actual;

    target.uri = expected;
    actual = target.uri;

    Assert.AreEqual(expected, actual);
}

This is where I'm stuck. The test compiles as expected and fails to run as expected. My next logical reaction is to write a test that says yep, if you give me a string for a Uri, I will fail:

[TestMethod()]
[ExpectedException(typeof(RuntimeBinderException), "Cannot implicitly convert type 'string' to 'System.Uri'")]
public void UriThrowsExceptionIfInvalidData()
{
    Site target = new Site();
    dynamic uri = "http://www.google.com";

    var expected = uri;
    Uri actual;

    target.uri = expected;
    actual = target.uri;

    Assert.AreEqual(expected, actual);
}

But now all I've done is validate what I already know. I'm uncertain how this helps me because the test's pass. I'm looking for that ahah moment that is going to get me to re-write my code to do some type checking to ensure that the Uri I'm going to set is a Uri. I'm sure that another ahah moment will come when I'm writing the type checking code and ask myself why I'm using dynamics for this?

I'm looking for the proper way to test that my Site.Uri is happy when it's passed a Uri, and not happy when it's not passed a Uri.

Community
  • 1
  • 1
Billy Coover
  • 3,827
  • 5
  • 36
  • 50

1 Answers1

1

I'm looking for the proper way to test that my Site.Uri is happy when it's passed a Uri, and not happy when it's not passed a Uri.

You just answered your own question.. write one test that tests that it fails as expected (as you have done), and a second test that tests it will work as expected when given the correct type.

[TestMethod()]
public void UriDynamicTestWorksWithCorrectParameter()
{
    Site target = new Site();
    dynamic uri = new Uri("http://www.google.com"); // note: correct type created here
    var expected = uri;
    Uri actual;

    target.uri = expected;
    actual = target.uri;

    Assert.AreEqual(expected, actual);
}

And are you sure that dynamic is what you need, why not just var?

Btw in your code the uri parameter is not dynamic (its just a string), data is the dynamic variable. So you are testing the wrong portion of your code can handle being a dynamic variable.

JK.
  • 21,477
  • 35
  • 135
  • 214
  • I'm trying to test the assignment of a strongly typed property (System.Uri) with a dynamically typed value who's type if not known until runtime (I'm not certain I'm even saying that correctly. Everything in the dynamic data property is going to be a string). var is probably ok for my current test since I know I'm trying to assign a string to a Uri, but I'm beginning to wonder if the test should actually include the deserialization of the JSON string, then the assignment of the property. – Billy Coover May 22 '11 at 13:18