views:

116

answers:

4

Updated version of question

Hi.

My company has a few legacy code bases which I hope to get under test as soon as they migrate to .NET 3.5. I have selected Moq as my Mocking framework (I fell in love with the crisp syntax immediately).

One common scenario, which I expect to see a lot of in the future, is where I see an object which interacts with some other objects.

I know the works of Michael Feathers and I am getting good at identifying inflection points and isolating decent sized components. Extract and Override is king.

However, there is one feature which would make my life a whole lot easier.

Imagine Component1 interacting with Component2. Component2 is some weird serial line interface to a fire central or somesuch with a lot of byte inspection, casting and pointer manipulation. I do not wish to understand component2 and its legacy interface consumed by Component1 carries with it a lot of baggage.

What I would like to do, is to extract the interface of Component2 consumed by Component1 and then do something like this:

 component1.FireCentral = new Mock<IComponent2> (component2);

I am creating a normal mock, but I am pasing in an instance of the real Component2 in as a constructor argument into the Mock object. It may seem like I'm making my test depending on Component2, but I am not planning on keeping this code. This is part of the "place object under test" ritual.

Now, I would fire up the real system (with a physical fire central connected) and then interact with my object.

What I then would wish for, is to inspect the mock to see a log of how component1 interacted with component2 (using the debugger to inspect some collection of strings on the mock). And, even better, the mock could provide a list of expectations (in C#) that would create this behavior in a mock that did not depend on Component2, which I would then use in my test code.

In short. Using the mocking framework to record the interaction so that I can play it back in my test code.

Old version of question

Hi.

Working with legacy code and with a lot of utility classes, I sometimes find myself wondering how a particular class is acted upon by its surroundings in a number of scenarios. One case that I was working on this morning involved subclassing a regular MemoryStream so that it would dump its contents to file when reaching a certain size.

// TODO: Remove
private class MyLimitedMemoryStream : MemoryStream
{
    public override void Write(byte[] buffer, int offset, int count)
    {
        if (GetBuffer().Length > 10000000)
        {
            System.IO.FileStream file = new FileStream("c:\\foobar.html",FileMode.Create);
            var internalbuffer = GetBuffer();
            file.Write(internalbuffer,0,internalbuffer.Length);
        }
        base.Write(buffer, offset, count);
    }        
}

(and I used a breakpoint in here to exit the program after the file was written). This worked, and I found which webform (web part->web part->web part) control rendered incorrectly. However, memorystream has a bunch of write's and writeline's.

Can I use a mocking framework to quickly get an overview on how a particular instance is acted upon? Any clever tricks there? We use Rhino Mocks.

I see this as a great assett in working with legacy code. Especially if recorded actions in a scenario easily can be set up as new expectations/acceptance criteria for that same scenario replicated in a unit test.

Every input is appreciated. Thank you for reading.

A: 

I don't think you can use a mocking framework to easily get an overview of how an particular instance is acted upon.

You can however use the mocking framework to define how it should be acted upon in order to verify that it is acted upon in this way. In legacy code this often requires making the code testable, e.g. introducing interfaces etc.

One technique that can be used with legacy code without needing to much restructuring of the code is using logging seams. You can read more about this in this InfoQ article: Using Logging Seams for Legacy Code Unit Testing.

If you want more tips on how to test legacy code, I recommend the book Working Effectively with Legacy Code by Michael Feathers.

Hope this helps!

BengtBe
A: 

Yes, this is possible. If you use a strict mock and run a unit test that exercises the mock, the test will fail, telling you which unexpected method was called.

Is this what you're looking for?

Judah Himango
Not exactly. If the mock had a log stating all interactions that was done to it, then that is what I was looking for. Or, even better, if the mock could wrap the real object and then be inspected afterwards for what was done to the object and how the object responded, then that would be what I was looking for.
Tormod
Ok. I don't think RhinoMocks or Moq has anything like this built-in. You might try looking into TypeMock, which is easily the most powerful mock framework.
Judah Himango
A: 

Mock frameworks weren't designed for this problem. I don't see how you can make this work with either Moq or RhinoMocks. Even the powerful TypeMock may not be able to do what you're asking. Mock frameworks weren't built for this.

Instead, use an aspect-oriented programming (AOP) tool to weave pre- and post- method invocation calls. This will do exactly what you want: see all interactions for a particular type. For example, in the PostSharp AOP framework, you simply specify methods you'd like called before and after a method call on some other object:

public class Component2TracerAttribute : OnMethodBoundaryAspect 
{ 
  public override void OnEntry( MethodExecutionEventArgs eventArgs) 
  { 
     if (eventArgs.Method == somethingOnComponent2) // Pseudo-code
     {
        Trace.TraceInformation("Entering {0}.", eventArgs.Method);  
     }
  } 

  public override void OnExit(MethodExecutionEventArgs eventArgs) 
  { 
      if (eventArgs.Method == somethingOnComponent2) // Pseudo-code
      {
         Trace.TraceInformation("Leaving {0}.", eventArgs.Method);   
      }
  } 
}

That will log all the methods that are called on component 2.

Judah Himango
+1  A: 

hi there.

Welcome to the small club of "visionaries" who understand this requirement :)

Unfortunately I'll tell you, I don't think this exists yet for .NET. I'm also pretty sure it doesn't exist for Java either... as I've been searching periodically for a few years, and even offered a cash bounty for this on a pay-for-work website, and nothing turned up (some Russian developer offered to implement it from scratch, but it was outside my budget).

But, I have created a Proof Of Concept in PHP to demonstrate the idea and perhaps other get people interested in developing this for other languages (.NET for you, Java for me).

Here is the PHP proof-of-concept:

http://code.google.com/p/php-mock-recorder/

Alex R
Thank you and welcome yourself.Indeed. Mocks should reproduce behaviour. Who is better to describe the interaction with a component than the component itself? This would make the effort of strapping a testing harness on objects would be much simpler and reduceable. You simply wrap everything with which you interact by default. If the recorded interaction does not make sense to describe in a test case, for example if the interaction is nonexistent or way too intense, you should probably rethink your choice of dependency boundary.A way more pragmatic approach to the problem.
Tormod