views:

50

answers:

3

I've got application A which runs application B as a console app. I'd like to write unit tests as part of application A which validate the input to/output from application B, but application B uses hard coded paths to look for some of its inputs. I'd like to be able to run the application, but intercept the call to read from c:\wherever\whatever.txt and provide the contents of that file myself.

Any frameworks or pieces which can do this for me?

A: 

This is almost impossible!! I say almost because it is possible to intercept calls in the CLR but it is black magic and not recommended unless you are a CLR developer - perhaps a few hundred people in the world.

You can make the hard-coded paths as command line parameters and solve your problem this way.

Aliostad
+1  A: 

This requires patching the Win32 CreateFile API function. Which is merely technically possible with Detours from Microsoft Research. Which requires unmanaged C or C++.

Tackle this problem at the source, having hard-coded path names in source code is unreasonable.

Hans Passant
A: 

You could include application B as a reference in application A, and then use Mocking frameworks to change the behaviour of B's methods or properties when calling it's API directly. This is the same process used for unit tests when setting up expectations on dependencies. There are limitations that generally this only works if the object in question is an interface, or contains vi rtual (overridable) methods/properties. The solution may also be dependent on being able inject a dependency into Bs API, which may or may not be possible depending on the scenario.

Moq, Rhino Mocks. and TypeMock all provide this functionality. Here's a quick example of Moq to override the behaviour of a GetPath method with an alternative value:

// create a mocked version of a class and setup an expectation
var appBClassMoq = new Mock<AppBClass>();
appBClassMoq.SetUp(o => o.GetPath()).Returns("C:\MyNewPath");

// get the mocked instance
var appBClass = appBClassMoq.Object;

// run some code, when it hits GetPath() it will return the mock value
appBClass.SomeMethodThatCallsGetPath();
TheCodeKing
BTW obviously this becomes a whole lot easier if you are writing both applications, in which case you would write your unit tests and code with testability in mind, and wouldn't ever touch the real file system.
TheCodeKing