perfectionist
perfectionist

Reputation: 4346

How do I record and replay method calls in c#.net for isolation testing of legacy code

I have a repository and a consumer of that repository in some legacy code.

The consumer makes multiple method calls to the repository.

Each method call returns a huge resultset.

I do have an integration test that checks how the consumer and repository behave together, but it isn't good enough for me - it relies on a database connection, is painfully slow, and doesn't help me know whether the test fails because of changes to the repository, database, or consumer.

I'd like to convert this integration test to test the consumer in isolation - independent of the implementation of the repository.

But because it is legacy code the behaviour of which I do not fully understand yet and because the resultsets are huge, I can't stub out the repository by hand. If it were possible to write this by hand it would look like

var mockRepository = new Mock<IRepository>();
mockRepository.SetUp(r => r.GetCustomersInMarket(marketId: 3))
    .Returns(
        new List<Customer> {
            new Customer {
                ...
                },
            new Customer {
                ...
                },
            ... x 100   // large dataset
            });
mockRepository.SetUp(r => r.GetProductsInMarket(marketId: 3))
    .Returns(
         ...
     );
... x 15   // many different calls need to be set up


var testee = new Consumer(mockRepository.Object); // using dependency injection

var report = testee.GenerateReport();

AssertReportMatchesExpectations(report);  // some assertions

So what I'd prefer to do is (once)

var recordingProxy = new RecordingProxy<IRepository>(new Repository());

var testee = new Consumer(recordingProxy);

var report = testee.GenerateReport();

var methodCallLog = recordingProxy.GetLog();

and thereafter

var methodCallLog = GetStoredMethodCallLog(); // load persisted log from file or similar

var replayingProxy = new ReplayingProxy<IRepository>(methodCallLog);

var testee = new Consumer(replayingProxy);

var report = testee.GenerateReport();

AssertReportMatchesExpectations(report);  // some assertions

I have started working on a generic tool to act as a proxy and record and replay traffic that goes across interface boundaries to solve this problem in general.

Is there already anything like this out there?

Are there other ways to solve the problem of stubbing repositories

If not, I'll be posting my tool as an answer to this question.

Upvotes: 3

Views: 506

Answers (0)

Related Questions