You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中使用mockall约束方法调用顺序:确保func1优先于func2和func3执行

如何用Mockall仅强制func1先于func2/func3调用(不限制后两者顺序)

当然可以实现你想要的效果!你提到的mockall::Sequence完全能搞定这个场景,只是不用把三个函数都塞进同一个序列里——咱们换个思路拆分就行。

核心思路

我们只需要确保func1的调用必须发生在func2和func3之前,但不对func2和func3的相对调用顺序做约束。具体做法是:

  • 创建一个序列,让func1占据序列的第一个节点
  • 让func2和func3的调用期望都依赖这个节点(也就是要求它们必须在func1调用之后执行)

修改后的完整代码

下面是调整后的示例代码,重点修改了main函数部分:

extern crate mockall;
use mockall::mock;
use mockall::predicate::*;
use mockall::Sequence; // 别忘了导入Sequence

fn do_thing<T>(x: T) where T: TestTrait {
    x.func1();
    x.func2();
    x.func3();
}

trait TestTrait {
    fn func1(self: &Self);
    fn func2(self: &Self);
    fn func3(self: &Self);
}

mock! {
    Test {}
    impl TestTrait for Test {
        fn func1(self: &Self);
        fn func2(self: &Self);
        fn func3(self: &Self);
    }
}

fn main() {
    let mut mock = MockTest::new();
    let mut seq = Sequence::new();

    // 让func1占据序列的第一个节点,返回可被依赖的调用节点
    let func1_call = mock.expect_func1().returning(|| ()).in_sequence(&mut seq);

    // 让func2和func3都必须在func1调用之后执行,互相之间无顺序要求
    mock.expect_func2().returning(|| ()).after(&func1_call);
    mock.expect_func3().returning(|| ()).after(&func1_call);

    // 两种合法顺序都会通过:
    // do_thing(mock); // 原顺序func1→func2→func3
    // 如果修改do_thing为func1→func3→func2,也会通过

    // 非法顺序(比如先调用func2再func1)会触发断言失败
}

关键代码解释

  • let mut seq = Sequence::new();:创建一个新的序列实例,用来标记调用顺序的依赖关系
  • mock.expect_func1().in_sequence(&mut seq):把func1的调用期望绑定到序列的第一个位置,返回一个可以被其他期望依赖的节点对象
  • .after(&func1_call):给func2和func3的调用期望添加依赖规则,要求它们必须在func1_call对应的调用(也就是func1的执行)完成之后才能被调用

这样设置后:

  • ✅ 合法顺序:func1→func2→func3、func1→func3→func2都会通过Mockall的断言验证
  • ❌ 非法顺序:任何先调用func2或func3再调用func1的情况,都会触发Mockall的调用顺序断言失败

内容的提问来源于stack exchange,提问作者LHLaurini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:42:39