CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Aaron Jensen

April 2008 - Posts

  • Mocking Events

    Currently in Rhino.Mocks, making mocks fire events and ensuring that an event on your SUT was fired are both awkward and verbose at best. Here is an example of both things at once:

    [Test]
    public void ViewFiresBeginDrag_Always_FiresChangedEvent()
    {
      IEventRaiser raiser;
      bool eventFired = false;
      using (Record)
      {
        The<ICardView>().BeginDrag += null;
        raiser = LastCall.IgnoreArguments().GetEventRaiser();
    
        Target.Changed += (x,y) => eventFired = true;
      }
    
      using (Playback)
      {
        raiser.Raise(The<ICardView>(), EventArgs.Empty);
        Assert.IsTrue(eventFired);
      }
    }

    Nice eh? First, is there a better way to do either of these things that I'm missing? Please tell me if so. Next, if not, what can we do to clean this up?

    Well, Ayende and I discussed this in the past and Ayende spiked it and asked for feedback. The feedback was mixed and for one reason or another it never made it into Rhino.Mocks that I know of.

    Well, today while I was working on Machine.Testing and another side project, I decided to give something else a shot. What I ended up with is this:

    [Test]
    public void ViewFiresBeginDrag_Always_FiresChangedEvent()
    {
      using (Record)
      {
        PrimeEventFiringOn<ICardView>(x => x.BeginDrag += null);
        Target.Changed += NewEventFireExpectation<EventHandler>();
      }
    
      using (Playback)
      {
        FireEventOn<ICardView>(EventArgs.Empty);
      }
    }

    Better, but I still don't think it's perfect. Also, it probably requires some explanation, so let's pick it apart piece by piece:

        PrimeEventFiringOn<ICardView>(x => x.BeginDrag += null);

    => +=??? Ugly huh? I really wish we could just refer to an event somehow without having to do +=/-=. At least I'm not using vb though... Alas, we cannot access them easily so we're stuck hacking away like this. So this particular method will basically get the mock or stub ICardView.BeginDrag ready to be fired. This needs to be done during the record phase it seems. You can only prime one event at a time per mock, so if you need to do more than one you can revert to the normal Rhino.Mocks syntax.

        Target.Changed += NewEventFireExpectation<EventHandler>();

    This was a fun method. This method actually creates a new DynamicMethod in the signature required by the event and creates a new delegate. The method tracks whether or not it was fired, and at the end of the Playback phase in my fixture it will assert that all of the events were actually fired.

        FireEventOn<ICardView>(EventArgs.Empty);

    This actually fires the event we set up in the Prime call. It can only be called after you've primed an event.

    So, the whole thing is kind of "magic", but it's less code if you can accept the magic. I think we can make things even better though, but it'd require changes to Rhino.Mocks and it's time for bed so maybe Ayende can swing by the Eleutian office while in Seattle and we can work on it. Here's what I'm thinking:

    [Test]
    public void ViewFiresBeginDrag_Always_FiresChangedEvent()
    {
      using (Record)
      {
        Target.Changed += Mocks.CreateEventHandler<EventHandler>();
      }
    
      using (Playback)
      {
        EventRaiser.Raise(() => The().BeginDrag += null, The<ICardView>(), EventArgs.Empty);
      }
    }

    There's probably more you can do with the CreateEventHandler syntax like add more specific expectations, assert its not fired, assert that it's fired X times, etc. The EventRaiser syntax is ugly, but it doesn't involve strings or the fire from the right hand side like the syntax I mentioned at the beginning of the post.

    You can get the source here, but I warn you it's first draft and there are hacky bits.

    Oh, and here's some example tests using the TestsFor fixture:

    [TestFixture]
    public class CardPresenterTests : TestsFor<CardPresenter>
    {
      private Card _card;
    
      public override void SetupContainer()
      {
        Override<ICardView>(With.Stub);
      }
    
      public override void BeforeEachTest()
      {
        _card = new Card(0);
      }
    
      [Test]
      public void OnBeginDrag_Always_SetsIsInFluxToTrue()
      {
        using (Record)
        {
          PrimeEventFiringOn<ICardView>(x => x.BeginDrag += null);
        }
    
        using (Playback)
        {
          FireEventOn(EventArgs.Empty);
    
          Assert.That(The<ICardView>().IsInFlux, Is.True);
        }
      }
    
      [Test]
      public void OnBeginDrag_Always_FiresChangedEvent()
      {
        using (Record)
        {
          PrimeEventFiringOn<ICardView>(x => x.BeginDrag += null);
          Target.Changed += NewEventFireExpectation<EventHandler>();
        }
    
        using (Playback)
        {
          FireEventOn<ICardView>(EventArgs.Empty);
        }
      }
    }
  • Book Review: Hacking Vim

    Some time ago, Packt Publishing sent me a copy of Hacking Vim: A Cookbook to get the Most out of the Latest Vim Editor by Kim Shulz to review. I read through it pretty quickly and I must say I thought it was a good book for the most part. The book is definitely focused at a very niche audience as there aren't a lot of us Vimmers around. Furthermore, I can't say I'd recommend the book for the casual Vimmer or those that use only ViEmu in Visual Studio. If, however, you are a moderate to hardcore Vim user or are interested in becoming one I would definitely recommend grabbing a copy.

    There is a lot of information in this book. It wastes no time or space describing the many ways to make your Vim experience even more efficient than it already is. Because of its very cut and dry style it reads more like a reference book than anything else, but I think that's perfectly fine for this style of book. It is essentially a slightly more readable, more detailed and better written version of a lot of the Vim help. It's also nice because in many of the chapters, especially the first few ("Better Navigation" and "Production Boosters") you can pick up a lot of interesting tips. I even learned a few handy commands I had no idea about.

    There's plenty of good information on writing Vim plugins and customizing Vim that I wish I would have had six years back when I wrote Vim plugins. Ah, looking at that code brings back fond memories, mostly involving learning Regular Expressions through trial and error and I actually used /// comments in C# code, but I digress.

    I also liked the stuff on firing Ruby from Vim--it reminded me I need to get a Ruby environment set up in Vim. Oh, and just for fun it seems, Kim even included an appendix showcasing some of the ridiculous things that have been written for Vim like Nibbles and Rubik's Cube. Heck, I just found a Twitter client for Vim (yea, I twitter now in case you care).

    There are a few things wrong with it though. Some things are too close to the Vim built-in help and you're probably better off just looking there. Also, the index isn't very useful and it'd be nice to have a searchable version of the book as well, so maybe the eBook version is a good idea. I wish all book companies would bundle eBooks with paper books, but, I digress again. Like I said, there is a lot of information in this book. It's not for everyone, but I think most Vim users will find plenty of useful stuff in its pages.

  • Separate Stub and Verify != Duplicate code necessarily

    Daniel Cazzulino, author of Moq posted a good comment on my last post where I suggested looking into a Mockito like syntax for .NET Mock Frameworks.

    On the surface, Mockito's approach seems good. But if you do the "true" comparison, you'll see that stub(...) is exactly the same as mock.Expect(...) in Moq.

    Then, when you do verify(...), you have to basically repeat the exact same expression you put in stub(...). This might work if you only have a couple calls to verify, but for anything else, it will be a lot of repeated code, I'm afraid.

    I thought this too. See my comment here from a month ago. Szczepan made a good point and I've thought about it more since then.

    When combined with my position on loose vs strict mocks (almost always use loose), I'd say that *most* of the time you are either stubbing or verifying. Meaning, if you're verifying you don't need to stub unless of course that method returns something that is critical to the flow of your test, in which case you don't really need to verify, because the flow would have verified. That's a mouthful, but does that make sense?

    I haven't used mockito, and I know there are times I use Expect.Call with return values that matter (which would essentially require you to duplicate stub & verify), but maybe that's a smell? Maybe if you think you need that you can do state based testing or change your API?

    Here's an example Test using Rhino.Mocks:

    [Test]
    public void SomeMethod_Always_CallsSendMail()
    {
      IMailSender sender = mocks.DynamicMock();
      UnderTest underTest = new UnderTest(sender);
    
      using (mocks.Record())
      {
        Expect.Call(sender.SendMail()).Returns(true);
      }
    
      underTest.SomeMethod();
    
      mocks.Verify(sender);
    }

    And some code this is testing (obviously not test driven, but you get the idea):

    public void SomeMethod()
    {
      if (!_sender.SendMail())
      {
        throw new Exception("OH NOS");
      }
    }

    Notice that here we would need to stub and verify separately with Mockito like syntax. This would look something like this:

    [Test]
    public void SomeMethod_Always_CallsSendMail()
    {
      IMailSender sender = mocks.DynamicMock();
      UnderTest underTest = new UnderTest(sender);
    
      Stub.That(() => sender.SendMail()).Returns(true);
    
      underTest.SomeMethod();
    
      Verify.That(() => sender.SendMail()).WasCalled();
    }

    This may violate DRY, but what if you designed your API differently? Maybe SendMail should throw an exception on failure instead of returning a boolean? This would make the return value unnecessary and remove the need for the Stub call. Clearly you can't always do this, especially with unwrapped legacy or API code, but it's something to think about.

    Also, I think you shouldn't be verifying more than one method generally to go along with the one assert/test rule, so a single repeat would not be that horrendous. Heck, you could even do:

    [Test]
    public void SomeMethod_Always_CallsSendMail()
    {
      IMailSender sender = mocks.DynamicMock();
      UnderTest underTest = new UnderTest(sender);
    
      Stub.That(var sendMail = () => sender.SendMail()).Returns(true);
    
      underTest.SomeMethod();
    
      Verify.That(sendMail).WasCalled();
    }

    I think the syntax would lead to better, more concise tests. But maybe it would just be too annoying? I wouldn't know until I tried it for a while I guess.

  • The Past, Present and Future (?) of Mocking

    (Note: I'm going to speak about .NET mock projects here for the most part, but most of them have Java quasi-equivalents.)

    The original mocking frameworks like NMock required you to setup expectations by passing strings for method names. This was fragile and made refactoring more difficult.

    A few mock frameworks now allow you to define expectations and mock results in a strongly typed manner. Rhino Mocks and TypeMock use a record/replay method to setup expectations. The record replay method is mostly necessary because the same calls are made on the same objects under two different scenarios. This leads to a few issues.

    The first issue is confusion and barrier to entry. Many people have complained that the Record/Replay method is not straight forward and the whole paradigm is confusing. There are also complains about the naming, are you really recording and then replaying? It's just kind of a strange thing. Of course most of us learn to live with it, understand it, and accept it for what it is. Recently though, a few mock frameworks have popped up that do away with this model.

    In the .NET world we have Moq. Moq gets rid of the need for record/replay because recordings have a very different syntax. They use lambdas instead of actual calls to the mock object. This allows the framework to know when you are recording an expectation and when you are fulfilling an expectation. It adds a bit of noise in the form of "() =>" but all in all it's not bad. Of course this requires C# 3.0, but it's good to keep looking ahead.

    In the Java world we have Mockito. Mockito also does away with the record/replay model but it does it in a different way. At first I wasn't a fan, but thinking about it more, I like it. Mockito has two main apis, stub and verify. Stub is equivalent to SetupResult.For, and verify is equivalent to Expect.Call with a verify. The interesting bit is that the stubbing happens before the the class under test is invoked and the verifying (which includes describing the method to be verified) happens after the class under test is invoked. This is best shown with an example stolen from the Mockito site:

      
      //stubbing using built-in anyInt() argument matcher
      stub(mockedList.get(anyInt())).toReturn("element");
      
      //stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher):
      stub(mockedList.contains(argThat(isValid()))).toReturn("element");
      
      //following prints "element"
      System.out.println(mockedList.get(999));
      
      //you can also verify using argument matcher
      verify(mockedList).get(anyInt());

    Obviously it would take a bit of imagination to arrive at a .NET equivalent, but you get the idea. I like this because the normal test structure is Setup Stuff->Do Stuff to Test->Verify Stuff did what it should have. The normal record/replay model requires you to set up verifications before you actually Do Stuff (though you call VerifyAll afterwards). This is a bit less natural. I feel syntax like this (yeah, I like the new NUnit syntax) would be more intention revealing:

    Assert.That(() => someMock.Foo(), Was.Called);

    Or:

    Verify.That(() => someMock.Foo()).WasCalled();

    Then you would stub like this:

    Stub.That(() => someMock.Bar()).Returns(3);

    (Note: No idea if this is feasible or makes sense or not, my lambda experience is limited to light reading, but you get the idea. I'm sure the syntax could also be prettier.)

    Rhino.Mocks is my current mock framework of choice. I'm used to it, I've lightly contributed to it, and I've been working with it for a while now. Despite that, I do think that there is definitely more to explore in the mocking arena especially with C# 3.0.

    There are lots of other fun things to talk about too... like TypeMock's magic, but that's another day still...

More Posts