views:

448

answers:

4

I'm trying to be better about unit testing my code, but right now I'm writing a lot of code that deals with remote systems. SNMP, WMI, that sort of thing. With most classes I can mock up objects to test them, but how do you deal with unit testing a real system? For example, if my class goes out and gets the Win32_LogicalDisk object for a server, how could I possibly unit test it?

+1  A: 

Is your question "How do I test against things that are hard/impossible to mock" such as your 'Win32_LogicalDisk" example or is it "How do I go beyond testing against mock objects to check that things will work in a production environment"?

+3  A: 

Assuming you meant "How do I test against things that are hard/impossible to mock":

If you have a class that "goes out and gets the Win32_LogicalDisk object for a server" AND does something else (consumes the 'Win32_LogicalDisk' object in some way), assuming you want to test the pieces of the class that consume this object, you can use Dependency Injection to allow you to mock the 'Win32_LogicalDisk' object. For instance:

class LogicalDiskConsumer(object):

    def __init__(self, arg1, arg2, LogicalDiskFactory)
        self.arg1=arg1
        self.arg2=arg2
        self.LogicalDisk=LogicalDiskFactory()

    def consumedisk(self):
        self.LogicalDisk.someaction()

Then in your unit test code, pass in a 'LogicalDiskFactory' that returns a mock object for the 'Win32_LogicalDisk'.

+1  A: 

You might create a set of "test stubs" that replace the core library routines and return known values, perhaps after suitable delays.

As an example, I recently needed to develop code to run inside a 3rd-party product. The challenge was that our "partner" would be doing the compiling and integration with their base code: I wasn't allowed to look at their code in any form! My strategy was to build a very simple emulator that did what I thought their code did, based on information from their engineers. We used a language that made it easy to switch various pieces of the emulator in and out of each build, so I could do a tremendous amount of testing before involving our partner to build each new iteration.

I'd use the same method again, as software problems in that particular product are about an order of magnitude fewer than in our next most reliable product!

Adam Liss
+1  A: 

The easiest way to test things which are hard to mock is to refactor the code in the way that your code (logic which is worth testing) is in one place and other things which your code use are in separate module(s). The module is easy to mock and this way you can focus on your business logic.

Marek Blotny