[][src]Module embedded_hal_mock::serial

Serial mock implementations.

You can set expectations for serial read and write transactions on a mock Serial device. Creating error transactions is supported as well.

Note that the embedded_hal crate provides both non-blocking and blocking serial traits. You can use the same mock for both interfaces.

Usage: Non-blocking serial traits

// Note that we're using the non-blocking serial traits
use embedded_hal::serial::{Read, Write};
use embedded_hal_mock::serial::{
    Mock as SerialMock,
    Transaction as SerialTransaction,
};

// Configure expectations
let expectations = [
    SerialTransaction::read(0x0A),
    SerialTransaction::read_many(b"xy"),
    SerialTransaction::write_many([1, 2]), // (1)
    SerialTransaction::flush(),
];

let mut serial = SerialMock::new(&expectations);

// Expect three reads
assert_eq!(serial.read().unwrap(), 0x0A);
assert_eq!(serial.read().unwrap(), b'x');
assert_eq!(serial.read().unwrap(), b'y');

// When designing against the non-blocking serial
// trait, we expect two separate writes. These could be
// expressed as two separate transactions, too. See (1) above.
serial.write(1).unwrap();
serial.write(2).unwrap();

// Finally, we expect a flush
serial.flush().unwrap();

// When you believe there are no more calls on the mock,
// call done() to assert there are no pending transactions.
serial.done();

Usage: Blocking serial trait

// Note that we're using the blocking serial write trait
use embedded_hal::blocking::serial::Write;
use embedded_hal::serial::Read;
use embedded_hal_mock::serial::{
    Mock as SerialMock,
    Transaction as SerialTransaction,
};

// Configure expectations
let expectations = [
    SerialTransaction::read(0x0A),
    SerialTransaction::read_many(b"xy"),
    SerialTransaction::write_many([1, 2]), // (2)
    SerialTransaction::flush(),
];

let mut serial = SerialMock::new(&expectations);

// Expect three reads
assert_eq!(serial.read().unwrap(), 0x0A);
assert_eq!(serial.read().unwrap(), b'x');
assert_eq!(serial.read().unwrap(), b'y');

// We use the blocking write here, and we assert that
// two words are written. See (2) above.
serial.bwrite_all(&[1, 2]).unwrap();

// Finally, we expect a flush. Note that this is
// a *blocking* flush from the blocking serial trait.
serial.bflush().unwrap();

// When you believe there are no more calls on the mock,
// call done() to assert there are no pending transactions.
serial.done();

Testing Error Handling

If you want to test error handling of your code, you can also add error transactions. When the transaction is executed, an error is returned.

use std::io::ErrorKind;
use embedded_hal_mock::MockError;

// Configure expectations
let expectations = [
    SerialTransaction::read(42),
    SerialTransaction::read_error(nb::Error::WouldBlock),
    SerialTransaction::write_error(23, nb::Error::Other(MockError::Io(ErrorKind::Other))),
    SerialTransaction::flush_error(nb::Error::Other(MockError::Io(ErrorKind::Interrupted))),
];
let mut serial = SerialMock::new(&expectations);

// The first read will succeed
assert_eq!(serial.read().unwrap(), 42);

// The second read will return an error
assert_eq!(serial.read().unwrap_err(), nb::Error::WouldBlock);

// The following write/flush calls will return errors as well
assert_eq!(
    serial.write(23).unwrap_err(),
    nb::Error::Other(MockError::Io(ErrorKind::Other))
);
assert_eq!(
    serial.flush().unwrap_err(),
    nb::Error::Other(MockError::Io(ErrorKind::Interrupted))
);

// When you believe there are no more calls on the mock,
// call done() to assert there are no pending transactions.
serial.done();

Structs

Mock

Mock serial device

Transaction

A serial transaction