However, this creates a few problems:
1) The C# code isn't fully parallel to the Java sample code
2) In the book, the end-to-end/acceptance tests operate at single level of scope, calling either ApplicationRunner or FakeAuctionServer to validate each step of the test. By using a mocked interface, I had to place the mock expected actions (replay and verify) at the top level (rather than inside AppicationRunner).
3) And, of course, it's not truly an end-to-end test, as it stops at the view interface.
I decided to experiment with writing some tests in a new project to see what the minimal amount of code would be necessary to create a simple WinForm inspector that could start simply by observing the activity of the status Label being set.
After a few false starts (and needing to review my knowledge of the ParmeterizedThreadStart class) I managed to get this working and displaying a label.
The tests:
[TestFixture]
public class WinFormInspectorTests
{
private WinFormInspector _winFormInspector;
[SetUp]
public void Setup()
{
_winFormInspector = new WinFormInspector(new Main());
}
[Test]
public void Inspector_Can_Instantiate_WinForm()
{
Assert.IsNotNull(_winFormInspector.Main);
}
[Test]
public void Inspector_Can_Launch_Application()
{
_winFormInspector.LaunchApplication();
_winFormInspector.SleepApplication(1000);
_winFormInspector.QuitApplication();
}
[Test]
public void Inspector_Can_Observe_Status_Label()
{
const string status = "Lost";
_winFormInspector.LaunchApplication();
_winFormInspector.Main.SniperStatus = status;
_winFormInspector.ShowsSniperStatus(status);
_winFormInspector.SleepApplication(1000);
_winFormInspector.QuitApplication();
}
}
The WinFormInspector class:
public class WinFormInspector
{
private readonly Main _main;
private Thread _thread;
public WinFormInspector(Main main)
{
_main = main;
}
public Main Main
{
get { return _main; }
}
public void ShowsSniperStatus(string expectedStatus)
{
if (!_main.SniperStatus.Equals(expectedStatus))
{
throw new Exception("Expected status does not match SniperStatus label.");
}
}
public void LaunchApplication()
{
_thread = new Thread(new ParameterizedThreadStart(Launch));
_thread.Start(this.Main);
}
public void SleepApplication(int sleepMilliseconds)
{
Thread.Sleep(sleepMilliseconds);
}
public void QuitApplication()
{
this.Main.Close();
Application.Exit();
}
private static void Launch(object input)
{
var form = (Form)input;
Application.Run(form);
}
}
...and the WinForm class, "Main":
public class Main : Form
{
private readonly Label _lblStatus;
public Main()
{
_lblStatus = new Label();
this.Controls.Add(_lblStatus);
}
public string SniperStatus
{
get
{
return _lblStatus.Text;
}
set
{
_lblStatus.Text = value;
}
}
}
My next step is to move this over into the AuctionSniper C# sample code project. One of the things I'm debating is whether to keep the mocked view tests as well.
No comments:
Post a Comment