I'm trying to mock out the serial port object provided by serialport::new() and having an awful time with it. The Rc<RefCell<dyn SomeTrait>> pattern is one I've been using for a while now for any singleton dependencies - like a serial port - and I've grown accustomed to it. It works and it lets me use mockall to write highly focused unit tests where all dependencies are mocked out.
But, today I ran into serialport::new(), which returns a Box<dyn SerialPort>, and I can't figure out a way to convert that into Rc<RefCell<dyn SerialPort>>. So I wrapped the whole box and ended up with Rc<RefCell<Box<dyn SerialPort>>>. But now I can't get my unit test to compile without defining the mock object in TestContext as another Rc<RefCell<Box<dyn SerialPort>>> - which would prevent me from being able to actually invoke special mock-related methods, like .expect_send().
I could use some help here. What follows is my use-case recreated in the simplest form possible as well as the compiler error that I get when building the test.
use std::cell::RefCell;
use std::rc::Rc;
/// This is not my code. This is a simplified version of the serialport crate.
mod serialport {
    pub trait SerialPort {
        fn send(&self);
    }
    pub struct SomeConcreteSerialPort {}
    impl SerialPort for SomeConcreteSerialPort {
        fn send(&self) {}
    }
    pub fn new() -> Box<dyn SerialPort> {
        Box::new(SomeConcreteSerialPort {})
    }
}
struct MyStruct {
    port: Rc<RefCell<Box<dyn serialport::SerialPort>>>,
}
impl MyStruct {
    fn new() -> Self {
        Self {
            port: Rc::new(RefCell::new(serialport::new())),
        }
    }
    fn do_send(&self) {
        self.port.borrow().send();
    }
}
fn main() {
    let my_struct = MyStruct::new();
    my_struct.do_send();
    println!("The foo is done!");
}
#[cfg(test)]
mod test {
    use mockall::mock;
    use std::cell::RefCell;
    use std::rc::Rc;
    use crate::serialport;
    use crate::MyStruct;
    mock! {
        SerialPort {}
        impl serialport::SerialPort for SerialPort {
            fn send(&self);
        }
    }
    struct TestContext {
        mock_port: Rc<RefCell<Box<MockSerialPort>>>,
        testable: MyStruct,
    }
    impl TestContext {
        fn new() -> Self {
            let mock_port = Rc::new(RefCell::new(Box::new(MockSerialPort::new())));
            Self {
                mock_port: Rc::clone(&mock_port),
                testable: MyStruct { port: mock_port },
            }
        }
    }
    #[test]
    fn test_happy_path() {
        let context = TestContext::new();
        context.mock_port.borrow().expect_send().once();
        context.testable.do_send();
    }
}
error[E0308]: mismatched types
  --> src/main.rs:71:44
   |
71 |                 testable: MyStruct { port: mock_port },
   |                                            ^^^^^^^^^ expected trait object `dyn SerialPort`, found struct `MockSerialPort`
   |
   = note: expected struct `Rc<RefCell<Box<(dyn SerialPort + 'static)>>>`
              found struct `Rc<RefCell<Box<MockSerialPort>>>`
I've also published the code to a GitHub repo if you'd like to reproduce it locally: https://github.com/DavidZemon/MockingProblems/