gists, net, testing, csharp comments edit

I’ve seen this question a few times in the Typemock forums so I figured I’d post a little something on it:

How do you mock a list using Typemock Isolator?

The challenge we currently have is that Isolator can’t mock types that are declared in mscorlib, which includes things like List<T>, so if you expose a list in your class, you have some potentially interesting mocking challenges, depending on how you choose to expose it.

If you wrap the list in methods/properties on your class, when you set up mocks, you’ll be setting up mocks against your class - not the list - so there is no problem there. If you expose the list as a public field, that’s where the challenge sets in.

Below is a code snippet showing an example class that does both things: it has a method and a property that “wrap” a list, and it has a public list field. Below that, you’ll see tests that illustrate different ways to handle the situations using Typemock Isolator.

public class ListExample
{
  // Publicly accessible list field
  public List<string> PublicList = new List<string>();

  // Private list that gets "wrapped" by methods/properties
  private List<string> _privateList = new List<string>();

  // Wraps the indexer of the private list
  public string this[int index]
  {
    get
    {
      return _privateList[index];
    }
    set
    {
      _privateList[index] = value;
    }
  }

  // Wraps the Add method on the private list
  public void Add(string value)
  {
    _privateList.Add(value);
  }
}

[TestFixture]
[VerifyMocks]
public class ListTestFixture
{
  // The problem we have is you can't mock types in mscorlib
  // so you need to either wrap the list or mock the field.

  [Test]
  public void WrappedList()
  {
    // If the list is "wrapped" in members of a type not
    // in mscorlib, we have it pretty easy because the
    // mocks get set up against the members on the ListExample
    // type, not against the List<T> object.

    ListExample example = new ListExample();
    using(RecordExpectations recorder = RecorderManager.StartRecording())
    {
      // No matter what index we ask for, we always want
      // the "expected" value to come back.
      string dummy = example[0];
      recorder.Return("expected");
      recorder.RepeatAlways();
    }

    // Put these values into the list...
    example.Add("a");
    example.Add("b");
    example.Add("c");

    // ...But what we get out is the mock value.
    // We can even ask for out of range indices.
    Assert.AreEqual("expected", example[0]);
    Assert.AreEqual("expected", example[1]);
    Assert.AreEqual("expected", example[2]);
    Assert.AreEqual("expected", example[3]);
    Assert.AreEqual("expected", example[4]);
  }

  [Test]
  public void FieldListMocks()
  {
    // Here the challenge is that there aren't any
    // members on the ListExample object that wrap
    // the list so we've actually got to "mock" the
    // list proper.

    // To accomplish the mock, we'll modify the object's
    // state by poking in our expected field value.
    ListExample example = new ListExample();
    ObjectState state = new ObjectState(example);
    List<string> expectedList = new List<string>();
    expectedList.Add("expected");
    state.SetField("PublicList", expectedList);

    // Now when we ask for the list, we're getting the
    // expected list, not the original member.
    Assert.AreEqual("expected", example.PublicList[0]);

    // When we're done, we can reset things back to the
    // original values, which means the real PublicList
    // will be back - and will still be empty.
    state.ResetState();
    Assert.IsEmpty(example.PublicList);
  }

  [Test]
  public void FieldListReflection()
  {
    // Of course, you can always do it the brute
    // force way, too, through reflection. It doesn't
    // look much different from the ObjectState version,
    // above, but we can't "return to the original
    // value" at the end of the test.
    ListExample example = new ListExample();
    List<string> expectedList = new List<string>();
    expectedList.Add("expected");

    typeof(ListExample)
      .GetField("PublicList",
        BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Public)
      .SetValue(example, expectedList);

    // Now when we ask for the list, we're getting the
    // expected list, not the original member.
    Assert.AreEqual("expected", example.PublicList[0]);
  }
}

As you can see, testing with the list solely as a backing data store and exposing the values only through members on your own class is far easier and less… code-smelly… than exposing the list directly as a field. Generally speaking, you shouldn’t expose public or protected fields anyway, opting for property get/set instead to allow for more flexible implementations later should the need arise. That said, if you have something you’ve got to test using a public list field, above are some ways to do it.

net comments edit

The Typemock Insider blog mentions that Patterns & Practices has adopted Typemock Isolator as their mocking framework, at least for testing SharePoint applications. Blaine Wastell and Francis Cheung say they’re using it because it allows them to mock sealed and internal types, which SharePoint is full of.

I think this is cool and definitely says something: Even if you’re writing brand new code, which can be entirely designed for testability (if that’s what you want), at some point you’re going to have to interface with something you didn’t write (SharePoint, .NET Framework) and you’re still going to want to test that interface code, which is where Isolator comes in. I’m so glad they’ve got an open source license now!

GeekSpeak comments edit

OK, my favorite Chrome Easter egg (actually, the only one I’ve heard, but still, so awesome) is if you type “about:internets” in the address bar. Too funny.

media comments edit

I got a “prototype system” up and running for a media center solution using my new Windows Home Server as the storage for the video. I set up a new shared folder called “DVD” on the home server and fixed it so it’s not using file duplication (no need eating up double the amount of space for each movie), then ripped a disc to it.

My laptop is running Vista Ultimate, so I set up the DVD Library to automatically watch for movies in the DVD shared folder and enabled it to play VIDEO_TS folder structures following the instructions here. Doing this worked perfectly and it played the ripped disc as though I had put it into the local drive. Exactly what I was looking for. It even played without glitches over the wireless network, which was surprising, but very cool.

The next step is to figure out how I want to deal with the media center itself. I know I’m going to need some sort of dedicated machine, so that will probably end up being a Mac Mini, similar to the “death of DVD” story I was reading. The question is, what software do I want to run?

  • Under Windows Vista Media Center, I have two choices:
    • The out-of-the-box DVD Library, which is the simplest way to go but doesn’t offer much in the way of searching/sorting by genre, cast, etc.
    • My Movies, a plugin for Media Center, which provides a much richer interface but also is higher-touch. There’s a server component I’d have to install on the Windows Home Server that, frankly, scares me because the WHS is working so well right now, I’d hate to start hacking on it.
  • Sticking with straight Mac, I have some choices, too (probably more than I’m aware of):
    • Front Row, which, as of version 10.5, finally supports playback of VIDEO_TS folders. Doesn’t look like it’s much richer than the DVD Library in Vista Media Center, but if I went Mac Mini, it’d require less to be installed on the Mac. (No Boot Camp running Vista, for example.)
    • Matinee, which looks pretty thin. I’m thinking if Front Row supports VIDEO_TS, I’d probably be best off with that over Matinee.
    • DistantDVD, which is also pretty thin but is specifically geared towards what I’m trying to do - play the video off the network. It doesn’t show any more info than the DVD Library, though, so, again, if Front Row supports VIDEO_TS over the network, that might be the way to go.

There are technically a lot of other choices for both platforms, but I’ve ruled out non-Windows-Media-Center choices for the Windows platform because I really don’t need most of the options the other servers offer and I don’t want to hassle with a lot of extra configuration and hackery. I didn’t list any different platforms for the Mac because, frankly, I’m ignorant. I’m really hoping to keep it simple, though, so as much out-of-the-box, it-just-works as I can get, the better.

It looks like it boils down to a small hierarchy of choices:

  • Do I need to have cast/genre/etc. information with the movies or is the title and cover art enough?
    • If I need more than title/cover art, My Movies seems to be the way.
    • If I don’t need more than title/cover art… Do I want to use out-of-the-box Mac stuff or do I want Vista Media Center?
      • If it’s OOTB Mac, which would be the easiest, it looks like Front Row is probably the answer.
      • If it’s Vista Media Center, DVD Library.

I’ll do a little more research on Front Row, but my media center solution is getting close…