I have a piece of code that gets a specific portion of the namespace from the calling assembly. Now I want to unit test this code. Is there a way to fake the name of the calling namespace using NUnit without implementing the NUnit testcase in that particular namespace?
Here is the method I want to test:
public static string FindCallingNameSpace()
{
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
if (stackFrames != null)
{
int nrFrames = stackFrames.Length;
for (int i = 0; i < nrFrames; i++)
{
var methodBase = stackTrace.GetFrame(i).GetMethod();
var Class = methodBase.ReflectedType;
if (Class != null && Class.Namespace != null && Class.Namespace != "Foo.Common.WebService")
{
var Namespace = Class.Namespace.Split('.');
return Namespace[1];
}
}
}
throw new Exception("Can't determine calling namespace! Need this to determine correct api url to call!");
}
An example would be:
Bar.ExampleNs.SomeMethod()
calls Foo.Common.WebService.CallApi()
which itself calls the method above to retrieve the namespace from SomeMethod()
. The result then would be "ExampleNs".
Now is it possible to create an NUnit UnitTest that is coded in the namespace MyUnitTests.ApiTest.TestNameSpace()
but inside Foo.Common.WebService
the call appears to come from Bar.ExampleNs.SomeMethod()
so I can test for "ExampleNs"?
I think by far the simplest way of achieving what you're after is to just create a call forwarder and call the
FindCallingNamespace
method via the forwarder. So, assuming that theFindCallingNamespace
method is in a classCallerStuff
you create this:Then in your test you call
RemoteCaller.Run
, rather thanCallerStuff.FindCallingNamespace
.However, you mentioned having Parameterized Tests, so presumably you might end up with a few different namespaces you want to test from which would mean more remote callers in different namespaces, which got me thinking that there might be a more generic approach.
The code below, essentially creates these wrapper classes for you by compiling them on the fly and then invoking them.
You would then invoke the method from your test:
Note, "SO.dll" in the example above is the name of the assembly containing the
CallerStuff.FindCallingNamespace
Using the compiler to generate the caller classes is probably overkill for what you're after and you might have to tweak the error handling in the code if you do decide to use it. If you're invoking the generated classes multiple times from different tests, then it may also be worth caching them, possibly through a dictionary keyed off namespace rather than compiling them every time. Compile + Call code is based on this blog post by Simeon Pilgrim.