Я думаю, что самый простой способ добиться того, что вам нужно, - это просто создать переадресацию вызовов и вызвать метод FindCallingNamespace
через экспедитор. Таким образом, если предположить, что метод FindCallingNamespace
в классе CallerStuff
создать этот:
namespace SomeNameSpace.ToTest {
static class RemoteCaller {
static public string Run() {
return CallerStuff.FindCallingNameSpace();
}
}
}
Тогда в тесте вы называете RemoteCaller.Run
, а не CallerStuff.FindCallingNamespace
.
Однако вы упомянули о параметризированных тестах, поэтому предположительно вы можете столкнуться с несколькими разными пространствами имен, которые вы хотите протестировать, из которых будет означать более удаленные абоненты в разных пространствах имен, что заставило меня думать, что может быть более общий подход ,
Код, по существу, создает для вас эти классы-оболочки, скомпилировав их на лету и затем вызывая их.
class CodeMaker {
static string _codesectionOne = @"
using Foo.Common.WebService;
namespace ";
static string _codesectionTwo = @" {
class RemoteCaller {
static public string Run() {
return CallerStuff.FindCallingNameSpace();
}
}
}";
public static string CompileAndCall(string targetNamespace,
string referenceAssembly) {
CompilerParameters CompilerParams = new CompilerParameters();
string outputDirectory = Directory.GetCurrentDirectory();
CompilerParams.GenerateInMemory = true;
CompilerParams.TreatWarningsAsErrors = false;
CompilerParams.GenerateExecutable = false;
CompilerParams.CompilerOptions = "/optimize";
string[] references = { "System.dll", referenceAssembly};
CompilerParams.ReferencedAssemblies.AddRange(references);
CSharpCodeProvider provider = new CSharpCodeProvider();
var codeToCompile = _codesectionOne + targetNamespace + _codesectionTwo;
CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams,
codeToCompile);
if (compile.Errors.HasErrors) {
string text = "Compile error: ";
foreach (CompilerError ce in compile.Errors) {
text += "rn" + ce.ToString();
}
throw new Exception(text);
}
Module module = compile.CompiledAssembly.GetModules()[0];
Type mt = null;
MethodInfo methInfo = null;
if (module != null) {
mt = module.GetType(targetNamespace + ".RemoteCaller");
}
if (mt != null) {
methInfo = mt.GetMethod("Run");
}
if (methInfo != null) {
return (string)methInfo.Invoke(null, null);
}
throw new InvalidOperationException("It's all gone wrong!");
}
}
Вы бы затем вызвать метод из теста:
Assert.AreEqual("Fiddle", CodeMaker.CompileAndCall("Wibble.Fiddle.Con", "SO.dll"));
Assert.AreEqual("Fuddle", CodeMaker.CompileAndCall("Wibble.Fuddle.Con", "SO.dll"));
Примечание «SO.dll» в приведенном выше примере это имя узла, содержащего CallerStuff.FindCallingNamespace
Использование компилятор для генерации классов вызывающего абонента, вероятно, слишком завышен для того, что вам нужно, и вам может потребоваться настроить обработку ошибок в коде, если вы решите его использовать. Если вы вызываете сгенерированные классы несколько раз из разных тестов, то также может быть целесообразно кэшировать их, возможно, используя словарь, исключающее пространство имен, а не компиляцию их каждый раз. Компиляция + Код звонка основан на this blog post от Simeon Pilgrim.
Не знаете, что мешает вам помещать ваш тестовый класс в пространство имен, которое вы хотите ... (обратите внимание, если вы из фона Java - пространства имен в C# не имеют отношения к имени сборки). –
В основном я хочу, чтобы мой тестовый код был чистым. Также было бы неплохо использовать Parameterized Tests. Мой OCD запускается, если у меня есть несколько пространств имен в одном файле. – mkeil
Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –