I Made a Unit Testing Mistake

I wrote some unit test code today to ensure that server workflow was working properly. This code worked consistently and quickly; regardless, there was an issue with the tests.

Oops

The code looked like this:

public void WaitForJobEventCompletion(int jobId, bool checkState = false)
{
	var startingState = string.Empty;
	if(checkState)
	{
		startingState = GetCurrentState(jobId);
	}
	
	PollUntilJobEventsCompleted(() => { return Controller.AllJobsCompleted(jobId); }, pollSpeed, timeout);
	
	if(checkState)
	{
		PollUntilStateChange(() => { return Controller.JobState(jobId) == startingState; }, pollSpeed, timeout);
	}
}

The method checks that job events have been processed and returns when they have or bubbles up an exception if they don’t before the defined timeout. Optionally, it can check that the state of the state machine has been updated as well.

Forget the problem that the method does more than its name implies. That’s not the major problem here.

The major problem is that the method is grabbing a start state, then waiting for jobs to finish, then checking that the state has changed. This begs the question, what if the jobs have already finished and the state has already changed when this method is run?

Well, if that happens then an exception will be generated every time because it will timeout on the poll for state change. That’s simply not acceptable.

I ended up factoring this into two separate methods:

public void WaitForJobEventCompletion(int jobId)
{
	PollUntilJobEventsCompleted(() => { return Controller.AllJobsCompleted(jobId); }, pollSpeed, timeout);
}

public void WaitForStateChange(int jobId, string startingState)
{
	PollUntilStateChange(() => { return Controller.JobState(jobId) == startingState; }, pollSpeed, timeout);
}

Now each method only does one thing — exactly what the name implies — and the start state is defined by the test, so if the state is expected to change the test can run this method with the starting state and expect the state to change as expected.

Once this was completed, my unit tests still worked consistently and quickly, but now they can be expected to work regardless of the speed of processing. They are easier to read due to the increased separation of concerns and simpler methods. Finally, they will need to be revisited less often due to the changed functionality.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s