Javaв„ў EE 5 Tutorial, The (3rd Edition)
You can start a new test class in a number of ways. Lee Holmes of Microsoft uses a keyboard macro to convert a new class file into a test class. See my Web site for an article about how to build a new template for a test class and install it into Microsoft Visual Studio. Often I just manually edit a new class, and I often write a first test that just runs trivially so that I can be sure that it is hooked up:
using System; using NUnit.Framework; namespace Notepad { [TestFixture] public class TestScroll: Assertion { [Test] public void HookUp() { Assert("hooked up", true); } } }
Once that works ”and it does ”I ll proceed to write the test I actually want:
[Test] public void ScrollHappens() { MockTextBox mock = new MockTextBox(); XMLNotepad notepad = new XMLNotepad(); Assert("no scroll", !mock.Scrolled); notepad.PutText(mock, lines, selectionStart); Assert("scroll happens", mock.Scrolled); }
I just sketched my intention here, and look what happened . I want to set up a MockTextBox, have it declare that it isn t scrolled, then put some text into it, and have it respond that now it is scrolled. My idea is that the MockTextBox will just set a flag when sent the ScrollToCaret. But look at the PutText message. I realized that I don t want to go through the Form if I don t have to, because the Form is doing all kinds of things to the model and textbox that I can t control. So I want not only the textbox parameter but also the lines and selectionStart to be parameters as well.
The test is telling me things about how the object should work.
However, I m getting in a bit deep here. It s time to dig out and make sure things are running. I m going to comment out a few lines of this test and then get it running:
[Test] public void ScrollHappens() { MockTextBox mock = new MockTextBox(); // XMLNotepad notepad = new XMLNotepad(); Assert("no scroll", !mock.Scrolled); // notepad.PutText(mock, lines, selectionStart); // Assert("scroll happens", mock.Scrolled); }
So I write a quick MockTextObject:
using System; namespace Notepad { public class MockTextBox { public MockTextBox() { } public Boolean Scrolled { get { return false; } } } }
That test runs. Now I ll uncomment the commented test lines and get to work. The program doesn t compile because lines and selectionStart aren t defined. We can fix that:
[Test] public void ScrollHappens() { int selectionStart = 1; string[] lines = new String[] { "hello", "world" }; MockTextBox mock = new MockTextBox(); XMLNotepad notepad = new XMLNotepad(); Assert("no scroll", !mock.Scrolled); notepad.PutText(mock, lines, selectionStart); Assert("scroll happens", mock.Scrolled); }
The compiler tells us that no overload for method PutText() takes three arguments. We knew that; that s what we are here to fix. So Back to XMLNotepad to fix PutText:
void XMLKeyDownHandler(object objSender, KeyEventArgs kea) { model.SetLines(textbox.Lines); model.SelectionStart = textbox.SelectionStart; if (kea.KeyCode == Keys.Enter) { model.Enter(); kea.Handled = true; } PutText(textbox, model.LinesArray(), model.SelectionStart); } public void PutText(TextBox textbox, string[] lines, int selectionStart) { textbox.Lines = lines; textbox.SelectionStart = selectionStart; textbox.ScrollToCaret(); // keep cursor on screen. no test. }
This nearly works, except (of course) that MockTextBox isn t a TextBox. I m tempted to have it subclass TextBox, but that s not likely to be a good idea: it would be inheriting lots of behavior that I don t understand, and the PutText method would be sending it messages. Instead, I m going to comment out the line that sends to it, and I ll test the GUI manually to be sure my new PutText is working. And it seems to be. The next step shouldn t be too hard, but it s a bit of a big one.