views:

51

answers:

2

I have to write a lot of code that deals with serial ports. Usually there will be a device connected at the other end of the wire and I usually create my own mocks to simulate their behavior.

I'm starting to look at Moq to help with my unit tests. It's pretty simple to use it when you need just a stub, but I want to know if it is possible and if yes how do I create a mock for a hardware device that responds differently according to what I want to test.

A simple example:

One of the devices I interface with receives a command (move to position x), gives back an ACK message and goes to a "moving" state until it reaches the ordered position.

I want to create a test where I send the move command and then keep querying state until it reaches the final position.

I want to create two versions of the mock for two different tests, one where I expect the device to reach the final position successfully and the other where it will fail.

Too much to ask?

+2  A: 

If you have an interface for a serial port object in your program, then Moq can do that by creating a mock serial port object (Moq is good for both stubs and mocks of any complexity).

If you'd like to intercept the calls to the BCL SerialPort class before they reach the hardware (without having to create a serial port interface and implementation, plus a test implementation), then you need something more powerful. That is what Moles is for.

If you want to actually emulate a device, then this goes beyond "unit testing." At this level, it's possible to use com0com to add a pair of virtual serial ports and write an emulator for your device that your tests can talk to. At this level, it's much more complex (though not impossible) to automate the testing.

Stephen Cleary
Yes, I already have an ISerialDrive, a SerialPortDrive and a couple of MockSerialPortDrive classes. I use the SerialPortDrive for my production code, and I use one mock for each type of device I'm testing. Some are pretty straight forward and could be easily replaced by a Moq mock, but others implement some smarter simulation of the hardware they connect.
Padu Merloti
A: 

If you're TDDing with mocks then you should let your tests define your objects. it already sounds like you have a design in mind before you've written any tests.

Your preliminary design has:

  • Command sender
  • Command reciever
  • Polling (asynchronous/synchronous)
  • By corollary you must have a Timeout function

That is already the responsibilities that your SerialController must implement. Wow that's a lot to implement without any tests in place.

Start nice and easy.

Try and test with the idea of 'Last Responsible Moment'.

Also what about the syntax you're going to use?

You might want to check this out: how-to-test-reliability-of-my-own-small-embedded-operating-system

I give links to Atomic Object's way of doing hardware and James Greening Blog. James has some good papers on doing TDD with hardware ( don't mind the ruby, c, and c++ stuff. If your doing hardware then you've played with the c and c++ before ;) ).

BTW, it looks pretty exciting what your doing.

Gutzofter
Thanks for the answer. All valid considerations, but I believe we are risking on falling into a discussion that is not at the core of my question. I've tried both styles and I still think having some design before testing is beneficial but I see both sides. My question though is more specifically geared towards how to use Moq to do something I'm currently doing manually.
Padu Merloti
@Padu - I think your comment to @Stephen reinforces my point '...but others implement some smarter simulation'. Mocking shouldn't have to simulate *smarter*. That is why I was trying to point out that your tests scenario has too much going on to effectively use a mock framework.
Gutzofter