views:

656

answers:

4

Using the new Rhino Mocks 3.5 Arrange/Act/Assert (AAA) Testing style, I'm having problems writing a test.

I have a method that calls a method on a repository class. ActivateFoo, where my Foo object has an IsActive property. The result of the ActivateFoo object should change the property.

Here is sample code:

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
  // arrange
  var repo = MockRepository.GenerateMock<IRepository>();
  var foo = new Foo() { ID = 1, IsActive = false };
  var target = new Presenter(repo);
  repo.Expect(x => x.ActivateFoo(foo)).Return(true);

  // act
  target.Activate(foo);

  // assert
  Assert.IsTrue(foo.IsActive);
  repo.VerifyAllExpectations();  
}

I'm guessing that the key piece of code would be inbetween "ActivateFoo(foo))." and "Return(true);".

One point to clarify how the method chaining stuff works behind the scenes, If there is code written on the line I expect, does it matter if it is after Return() or before? (unless of course the solution is using the MethodOptions overload of Expect, or something else).

Thanks in advance for any help.

A: 

Hi, I was not really using this version of RhinoMocks yet, but in the old versions you would have to use a .Do(appropriate delegate) to set the flag and return the value (instead of .Return).

Please let me know if it works, if not I can play around with it.

Grzenio
A: 

From the looks of it, ActivateFoo should be a void method. And since you are mocking it out, you shouldn't be verifying that it changes anything on your object.

You would verify that the IsActive property is changed when you were testing your repository method ActivateFoo, not when you are testing the Activate method on the presenter.

Bryan Rowe
A: 

You might want to try something out like this using the Do handler. I honestly feel ActivateFoo should be void return type. But here's the code for ActivateFoo with bool return type.

    [TestMethod]
    public void Should_update_foo_to_active_inside_of_repository()
    {
        // arrange
        var repo = MockRepository.GenerateMock<IRepository>();
        var foo = new Foo() { ID = 1, IsActive = false };
        var target = new Presenter(repo);
        repo.Expect(x => x.ActivateFoo(foo)).
            Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
        // act
        target.Activate(foo);

        // assert
        Assert.IsTrue(foo.IsActive);
        repo.VerifyAllExpectations();
    }

    private delegate bool ActivateFooDelegate(Foo f);

    public bool ActivateFooDelegateInstance(Foo f)
    {
        f.IsActive = true;
        return f.IsActive;
    }
AB Kolan
+1  A: 

Thanks to AB Kolan this is the resulting code I used and works.

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
    // arrange
    var repo = MockRepository.GenerateMock<IRepository>();
    var foo = new Foo() { ID = 1, IsActive = false };
    var target = new Presenter(repo);
    repo.Expect(x => x.ActivateFoo(foo)).
        Do(new Func<Foo, bool>(
            delegate(Foo f) { f.IsActive = true; return true; }
        ));

    // act
    target.Activate(foo);

    // assert
    Assert.IsTrue(foo.IsActive);
    repo.VerifyAllExpectations();
}

I tend to not like to have to have extra methods of functions for single use of a test, preferring an inline delegate if possible.

To address the issue of is this something I should be doing or not as far as the design. As the names are there, this isn't the exact code and inside of the target.Activate() method. The code in Activate() does some checking and if needed, will do the repository ActivateFoo(), and then check the result of that operation and do other things.

So, it might be possible that at a later time I will have to refactor this out and separate the steps, but for now, I've got it to work.

Thanks

Andre