views:

35

answers:

2

How would I test the following code?

   Public Sub SetSerialIdForDevice()
       Try
           Dim component As Object = container.getComponentRef("componentInterface")
           If component IsNot Nothing Then
               component.SetupDeviceSerialID(container.serialNumbers)
           Else
               serialfound = False
           End If
           Catch ex As Exception
            '' error handling
       End Try
   End Sub

Project references (or components as they're called here) are loaded at runtime into a singleton 'container.' We call the component that interfaces with a device by using the container.getComponentRef("< name of component we're looking for >"). We then invoke a method on this component to set the serial id, which is stored in a property of the container object.

In the SetupDeviceSerialID() method we call properties native to the 'container' (such as if it's an internal debug mode) as well as some other objects. What would be the best way to test this scenario where we have objects within objects? Would we mock all the calls, properties, and objects in order to isolate the test for SetupDeviceSerialID()?

Or do we mock the 'componentInterface' that's returned and mock the call for SetupDeviceSerialID() and then test the properties that were changed within SetupDeviceSerialID()?

EDIT

I've been thinking about testing this incorrectly (obviously) and through the answers I've come to realize that I was trying to cram testing for methods executed deeper in the code, into tests for the SetSerialIdForDevice() method.

So as a result, If a serialID is found, we would set serialfound = true inside of SetupDeviceSerialID().
Is that something we would test here (since we will be testing for serialfound=false), or in a test for SetupdDeviceSerialID()? And would we create a test to see if SetupDeviceSerialID() actually exists on the "componentInterface" component?

+2  A: 

I would mock container to have the getComponentRef return a mock object which the method can test against. Mocking each "componentInterface" class needs to be something that happens in their own dedicated unit tests. Don't combine testing responsibilities because its convenient, keep everything as its own unit so no unit test is dependent on another test.

cfeduke
+1  A: 

The mores Seams you can put into your code, the easier it becomes to test.

If you can replace the return value of the getComponentRef method with a Test Double, you can write one test that verifies that this method has been invoked correctly and then move on to writing other unit tests that verifies something else.

Ideally, you should only be writing one test that tests any particular piece of behavior.

Assuming you can replace the component variable with a Test Double, you could then verify that the SetupDeviceSerialID method is called correctly.

That, as well as some tets that exercise the error paths, should then conclude the test suite for the SetSerialIdForDevice method.

You can then move on to write a new set of tests that verifies that a particular 'component' implementation works as intended, but those would be separate tests that are independent of the tests that exercise the SetSerialIdForDevice method.

Mark Seemann