如果您可以在您尝试测试的代码上添加更多信息,那就太好了。根据您所写的内容,我可以猜到几个选项。
目前侵入性最小的可能是您在问题中建议的方法:为您想要伪造的成员添加一个接口或公共基类/适配器,virtual
以便可以通过模拟使用动态代理的库(如 NSubstitute 、起订量、FakeItEasy 和 Rhino 模拟)。
如果您有类似的东西IInputControl<T>
,T Value { get; set;}
那么您可以在测试中替换该类型。您必须更新代码以将引用存储为IInputControl<T>
而不是TextBox
,但这可能不是一件坏事,因为它将代码与TextBox
.
另一种选择(不确定您是否已经这样做了)是使用 Model-View-Presenter 样式,并且不要对视图如何将消息转换为TextBox
其他控件的细节进行单元测试。(您可以使用验收测试进行端到端测试。)
例如,假设您有一个演示者和视图界面,如下所示:
public class PersonPresenter {
public PersonPresenter(IPersonView view, IPersonQuery query) { ... }
public void Load() {
var person = query.Execute();
view.Name = person.Name;
view.Age = person.Age;
}
}
public interface IPersonView {
string Name { get; set; }
int Age { get; set; }
}
你可以用这样的东西进行测试:
[Test]
public void ShouldDisplayPersonOnLoad() {
var view = Substitute.For<IPersonView>();
var query = Substitute.For<IPersonQuery>();
query.Execute().Returns(new Person("A", 20));
var subject = new PersonPresenter(view, query);
subject.Load();
Assert.That(view.Name, "A");
Assert.That(view.Age, 20);
}
然后,您的实际视图可以委托给现有控件。这未经单元测试测试,但可能是可验收测试的,或者在视图更改时手动测试。理想情况下,这段代码应该足够简单,不会隐藏太多错误;这个想法是使视图尽可能简单,并且主要关注信息的外观,而不是逻辑。
public PersonView : IPersonView {
// ...
public string Name {
get { return nameTextBox.Value; }
set { nameTextBox.Value = value; }
}
public int Age {
get { return ageIntTextBox.Value; }
set { ageIntTextBox.Value = value; }
}
}