Best method in creating fake input Stream for arduino based unit testing with Unity

I’m looking to unit test my program with Unity, but I am unsure how to proceed in regards to creating a fake input stream.

I’m guessing the typical approach would be to create a sub-class of Arduino’s Stream object. Should I create this object from scratch? Is there a library or existing framework out there for this already?

I don’t think I need to ‘Mock’ anything. I just need to be able to update the Stream buffer with pre-defined bytes for testing.

Any suggestions?

1 Like

https://github.com/FabioBatSilva/ArduinoFake already has all you need for that.

This project builds the firmware for an Arduino Uno, but does testing on Desktop using mocking. (No on-target testing!)

Thank you, this is great!

I just have some questions:

  • Where do I find the documentation on Arduino Fake? or should I be reading the documentation of a different library?
  • I see setup() and loop() are run. How does the scope timeline work here? Do I only need to run setup once to initialise globals and etc? then does each call of loop() reset any global variables from previous tests? I would assume I would need a cleanup function to run after each test to reset globals.
  • I see Verify is used a lot. This seems to stop the whole test file when it fails instead of going to the next test. Is there something better I can use to abort the single test only? Is this a case for ASSERT...?
  • For sections like this
String fakedInput = "turnon";
    When(Method(ArduinoFake(Serial), available)).Return(fakedInput.length());
    When(Method(ArduinoFake(Serial), readStringUntil)).Return(fakedInput);
    When(Method(ArduinoFake(), digitalWrite)).AlwaysReturn();

I see the output is just mocked for the output of readStringUntil. If my code uses many buffer methods, is there a way I can just fake the buffer without having to have a custom mock for every method?

Thank you

ArduinoFake is built on FakeIt, which has docs. The rest must be read from the source files of ArduinoFake.

That depends on your code. If your setup() initializes its own objects needed by loop(), you need to run it.

It seems to me that a failed Verify() raises an exception which goes unhandled… So try to wrap it in a macro that does the try { /* verify() code } catch() { TEST_ASSERT(false); }.

Right, with the mocking functions, you would have to match the testing code to use exactly the same method as used by the code under tests. Sure, you can create your own C++ Serial replacement object, too.

Just wanted to update this thread. I have created my own solution to this issue. I can now use a mock stream object and run it all through PIO. It’s not optimal, but feel free to check it out with this public Git repo