我最近遇到了一个令我困惑的问题。我有一个C#4.0 Winform项目,我最初只使用TextBoxes。当我从TextBox切换到RichTextBox并且我的单元测试开始失败时,我的问题开始了。
我的第一个想法是编译器因改变变量的对象类型而感到困惑。所以我尝试了一个干净的构建,但是没有用。一位同事甚至建议更新Windows并重新启动,但问题仍然存在。
我将问题跟踪到RichTextBox的TextChanged事件未触发的事实。经过更多调查,我发现在我订阅TextChanged事件之前,如果我在调试模式下打开RichTextBox对象并只是查看它 - 测试将通过。但是我不希望每次运行测试时都要在调试模式下检查一个对象!
我发现这真的很好奇。我还发现运行程序通常会导致一切运行顺利。我很确定问题是单元测试实际上没有打开UI;仅使用Form对象。
这是我见过的第一个遇到此问题的控件。这就是让它如此奇怪的原因。令我感到困惑的是,RichTextBox和TextBox都扩展了TextBoxBase。在我的主程序中,我有DataGridViews,ListBoxes和TextBoxes在这些单元测试中工作正常,但由于某种原因RichTextBox发生故障。
任何人都可以解释为什么当许多其他控件没有激活时,RichTextBox基础需要用户界面?
我已将代码细化为仅显示问题部分:
Observer类观察TextBox和RichTextBox,并在TextBoxes发生更改时随时更新struct对象。如果我在订阅TextChanged事件之前检查调试模式中的richTextBox参数,则单元测试将通过。
public class Observer {
public DataStruct dataStructCopy { get; set; }
private TextBoxBase textBox { get; set; }
private TextBoxBase richTextBox { get; set; }
public Observer(DataStruct dataStruct, TextBoxBase textBox, TextBoxBase richTextBox) {
this.dataStructCopy = new DataStruct(dataStruct.textBoxText, dataStruct.richTextBoxText);
this.textBox = textBox;
this.richTextBox = richTextBox;
this.textBox.TextChanged += (o, e) => { this.dataStructCopy.textBoxText = textBox.Text; };
this.richTextBox.TextChanged += (o, e) => { this.dataStructCopy.richTextBoxText = richTextBox.Text; };
}
}
以下是我测试代码的方法:
[TestClass]
public class UnitTest1 {
private View view { get; set; }
[TestInitialize]
public void Initialize() {
this.view = new View();
}
//This method passes.
[TestMethod]
public void TestTextBox() {
string text = "text";
view.getTextBox().Text = text;
Assert.AreEqual(text, view.getTextBox().Text);
}
//This method passes.
[TestMethod]
public void TestRichTextBox() {
string text = "text";
view.getRichTextBox().Text = text;
Assert.AreEqual(text, view.getRichTextBox().Text);
}
//This method fails.
[TestMethod]
public void TestObserver() {
string text = "text";
string richText = "rich";
view.getTextBox().Text = text;
view.getRichTextBox().Text = richText;
Assert.AreEqual(text, view.observer.dataStructCopy.textBoxText);//this works
Assert.AreEqual(richText, view.observer.dataStructCopy.richTextBoxText);//this fails
}
}
我想在这里展示两件事。首先,我能够在不实际加载UI之前成功测试其他控件。我还试图证明RichTextBox能够处理其Text属性的更改 - 问题在于其TextChanged事件,因为DataStruct无法更新。
提前致谢!