1

Every body seems to be talking about TDD and BDD these days so i thought i give it a try on a smallish home project.

A short backgrund I am developing a class Device in a C extension that interacts with a native C API for controlling remote devices like light switches and so on.

To make the tests more platform independent I have mocked out the C API to behave as the original one but instead of controlling hardware it sets a global ruby state variable (a hash containing all the devices).

This is all fine and works as expected. I can compile and link to this library instead of the real one.

Now the part i need help with is how to test this following some sort of best practice I have the following spec to describe my Device class

  describe Device do
    describe ".get" do
      context "Specified id exists" do
        it "Returns a instance of Device"
        it "Device has same id as specified"
      end
      context "Specified id is undefined"
        it "throws UndefinedDeviceException"
      end
    end
    describe "#turn_on" do
      context "Device supports turning on" do
        # I set up the mock state to have a device that supports on..
        # how do i get the Device instance here? is it ok to depend on
        # Device.get method?
        it "Returns true"
        it "Set device state to on" # Check mocked state
      end
    end
    .....
  end

Now as far as i understand in each context i setup the state for my mocked library to reflect what I want to test and i invoke the method. This works well for the static method Device.get(id) because this returns a new Device what I'm not sure on how to test is the instance methods. If I want to test the method turn_on i need to have a instance of Device first which means i need to call Device.get to actually get the device? but if that's the case arnt I again "testing" the class method get? I guess what I'm really asking here is whats a good practice to get a instance of a object in Rspec if it depends on an external library.

Patrik
  • 255
  • 3
  • 11

1 Answers1

1

Calling Device.get sounds find to me - in those tests you'll be testing some method of the returned Device object rather than get itself.

While tests are supposed to be independent, you will inevitably end up with some tests that use methods tested by other tests - for example the active record test suite has plenty of tests for create and find but those methods are used by lots of other tests too.

What can be tricky in this area is deciding at what level to mock - you can end up just testing your mocks and none (or little) of the actual implementation.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • Allright then I'm on the right track i guess. Thanks Regarding just testing mocks I guess its a trade-off. In my particular case the level of abstraction from the C API is quite big so i think its worth testing. – Patrik May 14 '15 at 12:08