A collection of virtual interfaces and googletest mocks for Arduino that replace libraries directly interacting with the hardware.
These can be used as arguments for classes and functions allowing the author to write native c unit tests using the dependancy injection pattern.
This is not an official Google product.
This document assumes that you know how to write unit tests using the googletest library and how to use the mocks and write mock expectations via the googlemock library. If you need the refresher, see the following documents:
The following abstractions are provided:
- arduino_interface.h - abstraction for Arduino's builtin functions like digitalRead, delay, ...
- dht_interface.h - abstraction for the Adafruit DHT sensor library.
- adafruit_pcd8544_interface.h - abstraction for the Adafruit PCD8544 Nokia 5110 LCD library.
Each abstraction comes with these components:
- A virtual interface.
- A mock implementing the virtual interface.
- An Arduino native implementation of the virtual interface.
Let's say that you want to unit test a function that uses the Arduino's digitalWrite() function.
To do that, instead of importing Arduino.h and having the function call digitalWrite() directly, you will use dependancy injection. Import the virtual interface and accept it as an argument on the function.
Your function can be defined as follows:
#include <stdint.h>
#include "arduino/arduino_interface.h"
// Turns on the provided pin number.
void WriteHighToPin(const arduino::ArduinoInterface &ino, uint8_t pin_number) {
ino.DigitalWrite(pin_number, 1);
}
The main file of your Arduino project will import the actual native implementation of the virtual interface and pass that in to the function.
#include <Arduino_impl.h>
// Arduino hardware layer.
const ArduinoImpl ino = ArduinoImpl();
const uint8_t kPinNumber = 13;
void setup() {
WriteHighToPin(ino, kPinNumber);
}
void loop() {
// Your code here.
}
Since the WriteHighToPin() function uses dependancy injection, it is now trivial to write unit tests where you can pass in the provided mock and write expectations.
#include "arduino/arduino_interface_mock.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
const uint8_t kPinNumber = 13;
TEST(WriteHighToPinTest, WritesHighToPin) {
const arduino::MockArduinoInterface mock;
EXPECT_CALL(mock, DigitalWrite(kPinNumber, 1));
WriteHighToPin(mock, kPinNumber);
}
Examine the unit tests included with each of the virtual interfaces to see how unit tests using these abstractions can be written.