Reputation: 1509
I have a method that finds a class using reflection, and I want to unit test it.
In assembly to be tested:
namespace MyApp.Workers
{
internal interface IWork { void DoWork() }
internal class RealWork : IWork { public void DoWork() { /* impl omitted */ } }
}
namespace MyApp.Helpers
{
internal static class ClassFetcher
{
public static Type GetWorkClass(string className)
{
string qualifiedClassName = typeof(IWork).Namespace + "." + className;
cls = Type.GetType(qualifiedClassName);
if (cls == null)
throw new Exception($"Can't find class \"{className}\".");
if (!typeof(IWork).IsAssignableFrom(cls))
throw new Exception($"The class \"{className}\" doesn't implement IWork.");
}
}
}
In test assembly:
// Usings omitted...
namespace MyApp.Workers
{
// Class that does implement IWork.
public class TestWork : IWork { public void DoWork() {} }
// Class that does not implement IWork.
public class TestNoWork { }
}
namespace MyApp_Test.Helpers
{
[TestClass]
public class UnitTestClassFetcher
{
[TestMethod]
public void FindsWorkClass()
{
ClassFetcher.GetWorkClass("TestWork");
}
[TestMethod]
public void DoesNotAcceptNoWorkClass()
{
ClassFetcher.GetWorkClass("TestNoWork");
}
}
}
On the GetWorkClass
calls from the test assembly, the Type.GetType(...)
call inside GetWorkClass
returns null. If I pass "RealWork"
from the test method it works.
So, how can I enable the Type.GetType(...)
call inside the assembly to be tested to find the test classes that are declared inside the unit test assembly?
Suggestions both with and without third-party frameworks, tools, addons are welcome.
SOLUTION As per the comment from @LasseV.Karlsen and the marked answer from @dymanoid, I just changed the test method's code like this:
[TestMethod]
public void FindsWorkClass()
{
string namespace = typeof(IWork).Namespace;
string className = typeof(TestWork).AssemblyQualifiedName.Substring(namespace.Length + 1);
ClassFetcher.GetWorkClass(className);
}
Upvotes: 1
Views: 844
Reputation: 15227
You need to use the AssemblyQualifiedName, because your test type resides in a different assembly, not where the GetWorkClass
method is defined. Without providing the full assembly qualified name, the Type.GetType
method searches only in the executing assembly and in mscorlib
.
Either change your method's implementation such that it uses assembly qualified names (e.g. by providing the assembly name as an optional parameter), or define the TestWork
class in the same assembly where the GetWorkClass
is defined (that's not a good suggestion, however).
Upvotes: 1