views:

96

answers:

1

The desired functionality of the 'enhanced' combo box is a quick find method. Each item in the combobox has a ToString() method, such that they can be displayed in the drop down list. On clicking an item in the drop down list, the combobox's observers are notified of the selection.

Also, every time the typed text in the combobox changes, a list of "Candidates" is generated, made of all those items in the drop down list which contain the text typed in so far. Hitting enter takes you to the first candidate in that list, repeatedly hitting enter cycles you through the list.

I've implemented this functionality by deriving from ComboBox - I figured this made sense as I'm still functionally left with a combobox, it just has this "QuickFind" feature added. However, the logic to create the candidate list and cycle through it, whilst simple, isn't totally trivial, and would enjoy some testing.

However, as seen here it doesn't seem to be all that easy to test a ComboBox just by constructing it and prodding the extra routines I've added - it needs to exist on a form for it to behave the same way as it does in the application. This seems altogether too much effort to test a simple addition to a simple combo box!

Nothing in the code to cycle through the candidates is specific to my application however - I have created a general control that may be used in any number of contexts, the only requirement being that the objects in the combobox have a ToString() methiod, which is the same restriction placed on objects going into normal comboboxes anyway, and is guaranteed by C# .NET.

So, with testability in mind, where would you put the enhanced functionality?

+1  A: 

As with the post you references: seperating the logic from the gui elements is also the solution here.

You should consider using a controller-like class which exposes a list of items which you can databind to your ComboBox' DataSource. The controller itself is responsible for maintaining this list.

So whenever you type a letter in the ComboBox you call a function on the controller, let's say UpdateList(string typedString). In this way you have seperated the logic of filling the list with 'candidates'.

Now you can easily write a number of tests which each call UpdateList() with different arguments and inspect the list of items afterwards. No GUI stuff needed to do the testing, you're only testing the algorithm itself.

Gerrie Schenck
Thanks Gerrie - something's clicking a bit better here than when you answered previously! How do I know however that I have hooked the UpdateList calls into the correct events? Do I just have to make this part of the logic simple enough that inspection will do?
Paul Smith
I don't understand your question completely, but you want to test the logic behind filling the candidate list, right? So for now forget about wiring events to the UpdateList method. How the method will be used is another thing, in your case it will be triggered by a ComboBox event and in your test.
Gerrie Schenck
Maybe my unit testing philosophy is what's wrong. I can isolate the "Candidate list" into its own class, but how do I test the "When I hit Enter, the next candidate is displayed" requirement? Sure, I can test "When I call f(), the next candidate is requested" and I can get "When I hit Enter, f()"
Paul Smith
... is called" only by visual inspection. Key processing in Windows Forms is 'hard' - I don't know how to be sure that I've overridden the correct method/hooked up to the right events. When I'm not sure, I usually use a test, but I can't seem to write a sufficient test.
Paul Smith