ОБНОВЛЕНИЕ: Я изменил формулировку вопроса. Раньше было да/нет вопроса о том, можно ли изменить базовый класс во время выполнения.Как мне подделать/подделать/заменить/заглушить базовый класс при единичном тестировании на C#?
Возможно, я работаю над выполнением миссии, но я, кажется, приближаюсь. Я хочу расширить элемент управления ASP.NET, и я хочу, чтобы мой код был единым проверяемым. Кроме того, я хотел бы иметь возможность подделывать поведение реальной метки (а именно такие вещи, как генерация идентификаторов и т. Д.), Которые настоящий ярлык не может сделать на узле nUnit.
Здесь рабочий пример, который делает утверждения о чем-то, что зависит от реального базового класса и чего-то, чего нет ... в более реалистичном модульном тесте, испытание будет зависеть от обоих --i.e. существующий идентификатор и некоторое пользовательское поведение.
Во всяком случае код говорит, что это лучше, чем я могу:
public class LabelWrapper : Label //Runtime
//public class LabelWrapper : FakeLabel //Unit Test time
{
private readonly LabelLogic logic= new LabelLogic();
public override string Text
{
get
{
return logic.ProcessGetText(base.Text);
}
set
{
base.Text=logic.ProcessSetText(value);
}
}
}
//Ugh, now I have to test FakeLabelWrapper
public class FakeLabelWrapper : FakeLabel //Unit Test time
{
private readonly LabelLogic logic= new LabelLogic();
public override string Text
{
get
{
return logic.ProcessGetText(base.Text);
}
set
{
base.Text=logic.ProcessSetText(value);
}
}
}
[TestFixture]
public class UnitTest
{
[Test]
public void Test()
{
//Wish this was LabelWrapper label = new LabelWrapper(new FakeBase())
LabelWrapper label = new LabelWrapper();
//FakeLabelWrapper label = new FakeLabelWrapper();
label.Text = "ToUpper";
Assert.AreEqual("TOUPPER",label.Text);
StringWriter stringWriter = new StringWriter();
HtmlTextWriter writer = new HtmlTextWriter(stringWriter);
label.RenderControl(writer);
Assert.AreEqual(1,label.ID);
Assert.AreEqual("<span>TOUPPER</span>", stringWriter.ToString());
}
}
public class FakeLabel
{
virtual public string Text { get; set; }
public void RenderControl(TextWriter writer)
{
writer.Write("<span>" + Text + "</span>");
}
}
//System Under Test
internal class LabelLogic
{
internal string ProcessGetText(string value)
{
return value.ToUpper();
}
internal string ProcessSetText(string value)
{
return value.ToUpper();
}
}
Я согласен с вами в том, что во время выполнения не существует способа изменить базовый класс. Я все еще надеюсь найти образец, чтобы имитировать его. Но я не уверен (если это было возможно), как это отличается от фабрики, которая возвращает альтернативные реализации, которые имеют один и тот же базовый класс или поддерживают один и тот же интерфейс. Завод может выбрать вредоносную реализацию или недействительную реализацию. – MatthewMartin