我有一个使用反射查找类的方法,我想对它进行单元测试。
在待测试的装配中:
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.");
}
}
}
在测试装配中:
// 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");
}
}
}
在来自测试程序集的GetWorkClass
调用中,Type.GetType(...)
内的GetWorkClass
调用返回null。如果我从测试方法中传递"RealWork"
就可以了。
那么,如何在要测试的程序集中启用Type.GetType(...)
调用以查找在单元测试程序集中声明的测试类?
欢迎使用和不使用第三方框架,工具,插件的建议。
解 根据@ LasseV.Karlsen的评论和@dymanoid的明确答案,我只是更改了测试方法的代码:
[TestMethod]
public void FindsWorkClass()
{
string namespace = typeof(IWork).Namespace;
string className = typeof(TestWork).AssemblyQualifiedName.Substring(namespace.Length + 1);
ClassFetcher.GetWorkClass(className);
}
答案 0 :(得分:1)
您需要使用AssemblyQualifiedName,因为您的测试类型位于不同的程序集中,而不是GetWorkClass
方法定义的位置。如果不提供完整的程序集限定名称,Type.GetType
方法仅在执行程序集和mscorlib
中搜索。
更改方法的实现,使其使用程序集限定名称(例如,通过提供程序集名称作为可选参数),或者在定义TestWork
的同一程序集中定义GetWorkClass
类(但这不是一个好建议。)