EasyNmeaImpl Unit Tests

As documented in Implementation Level, EasyNmeaImpl provides with the implementation for the EasyNmea public API, namely opening and closing the serial port, waiting until data of one or more NMEA 0183 types has been received, checking whether the serial port connection is opened, and taking the next unread sample of a given NMEA 0183 type.

The EasyNmeaImpl tests use the EasyNmeaImplTest class, which derives from EasyNmeaImpl, adding the possibility of substituting the SerialInterface with another instance. This enables the tests to implement a SerialInterfaceMock, which derives from SerialInterface, mocking away the SerialInterface::open(), SerialInterface::is_open(), SerialInterface::close(), and SerialInterface::read_line() functions. This way, the tests can substitute the SerialInterface instance in EasyNmeaImplTest with an instance of SerialInterfaceMock on which expectations can be set, and then check whether EasyNmeaImpl behaves as expected depending on the SerialInterface returned values.

@startuml
hide empty members

class EasyNmeaImpl

EasyNmeaImplTests : void set_serial_interface(SerialInterface<>* serial_interface)

SerialInterfaceMock : MOCK_METHOD(open)
SerialInterfaceMock : MOCK_METHOD(is_open)
SerialInterfaceMock : MOCK_METHOD(close)
SerialInterfaceMock : MOCK_METHOD(read_line)

class SerialInterface<asio::serial_port>

SerialInterface <|-- SerialInterfaceMock
EasyNmeaImpl o-- "1" SerialInterfaceMock
EasyNmeaImpl <|-- EasyNmeaImplTests
@enduml

open()

  1. openSuccess: Opens a not previously opened EasyNmeaImpl. The return is expected to be ReturnCode::RETURN_CODE_OK.

  2. openOpened: Attempts to open an already opened EasyNmeaImpl. This is simulated by forcing SerialInterface::is_open() to return true. The return is expected to be ReturnCode::RETURN_CODE_ILLEGAL_OPERATION.

  3. openWrongPort: Attempts to open a EasyNmeaImpl on an invalid port. This is simulated by forcing SerialInterface::open() to return false. The return is expected to be ReturnCode::RETURN_CODE_ERROR.

is_open()

  1. is_openOpened: Check that whenever SerialInterface::is_open() returns true, EasyNmeaImpl::is_open() also returns true.

  2. is_openClosed: Check that whenever SerialInterface::is_open() returns false, EasyNmeaImpl::is_open() also returns false. Furthermore, this test also checks that EasyNmeaImpl::is_open() returns false whenever the underlying pointer to SerialInterface is nullptr.

close()

  1. closeSuccess: Check that whenever SerialInterface reports that a port is opened at first, and then return true on the call to SerialInterface::close(), then EasyNmeaImpl::close() returns ReturnCode::RETURN_CODE_OK.

  2. closeError: Check that whenever SerialInterface reports that a port is opened at first, and then return false on the call to SerialInterface::close(), then EasyNmeaImpl::close() returns ReturnCode::RETURN_CODE_ERROR.

  3. closeClosed: Check that calling EasyNmeaImpl::close() on a non-opened EasyNmeaImpl returns ReturnCode::RETURN_CODE_ILLEGAL_OPERATION.

wait_for_data()

  1. wait_for_dataData: Check that EasyNmeaImpl::wait_for_data() returns ReturnCode::RETURN_CODE_OK when a sentence which type specified in the NMEA0183DataKindMask mask is received. Furthermore, check that the output mask has the corresponding bit correctly set.

  2. wait_for_dataClosed: Check that EasyNmeaImpl::wait_for_data() returns ReturnCode::RETURN_CODE_ILLEGAL_OPERATION when called on a closed EasyNmeaImpl.

  3. wait_for_dataDataEmptyMask: Check that EasyNmeaImpl::wait_for_data() will return ReturnCode::RETURN_CODE_TIMEOUT after timing out when an empty NMEA0183DataKindMask is passed, even when data from any of the supported types has been received. It also checks that the output NMEA0183DataKindMask is set to none.

  4. wait_for_dataError: Check that whenever SerialInterface::read_line() returns false, the call to EasyNmeaImpl::wait_for_data() unblocks and returns ReturnCode::RETURN_CODE_ERROR. It also checks that the output NMEA0183DataKindMask is set to none.

take_next()

  1. take_next: Check that whenever EasyNmeaImpl::wait_for_data() returns ReturnCode::RETURN_CODE_OK, then, data can be taken with EasyNmeaImpl::take_next(), which returns ReturnCode::RETURN_CODE_OK. Furthermore, it tests that other NMEA 0183 valid sentences are not returned nor reported to be have been received, and that incomplete GPGGA sentences are not returned nor reported either.

~EasyNmeaImpl()

  1. destroyNoClose: Checks that letting an opened EasyNmeaImpl instance go out of scope without calling EasyNmeaImpl::close() is alright.