我有一个想要测试的函数,它在输入上引发异常,但该异常还携带了一些比普通消息更多的信息,我也想测试它。所以我做了类似的事情,如 rspec 文档中所示:
it 'raises the correct exception' do
expect { my_call }.to raise_error do |error|
expect(error.some_field).to eq('some data')
end
end
Run Code Online (Sandbox Code Playgroud)
这很有效,但它与RSpec/MultipleExpectations警察发生了冲突:
RSpec/MultipleExpectations: Example has too many expectations [2/1]
Run Code Online (Sandbox Code Playgroud)
据我所知,raise_error在没有超过一个预期的情况下不可能以这样的块形式使用,那么给出了什么?有没有某种方法可以以某种方式将引发的异常保存在示例之外,以便我可以正常规范它,而不需要rescue在规范中做一些可怕的事情?或者我应该使用自定义raise_custom_error匹配器?
我有一个这样的结构:
#[derive(Serialize, Deserialize)]
struct Thing {
pub small_header: Header,
pub big_body: Body,
}
Run Code Online (Sandbox Code Playgroud)
我想将其序列化Thing以通过网络发送。我已经有一个Body可用的但我无法移动它(想象一下我正在用它做某事,我不时收到一个命令来暂时停止我正在做的事情并发送我现在拥有的任何数据)并且我可以不要复制它(它太大了,可能有数百兆字节)。
所以我希望 Serde 只借用我所拥有的序列化它,因为它不需要为此移动到结构中。如果我重写Thing拿个参考,我显然推不出来Deserialize!
我一直在使用的解决方法是Arc<Body>在我的代码中使用一个,这样我就可以在我的正常逻辑中使用主体,当我需要序列化它时,我可以做一个廉价的克隆并将其Arc<Body>放入结构中进行序列化. 在反序列化期间,Serde 将创建Arc一个引用计数为 1的新对象。
这仍然涉及散布Arc在我的代码中,这不是很好,更不用说不必要的(尽管很小)运行时成本。此用例的正确解决方案是什么?
有趣的是,如果我不必发送标头,那么这将不是问题,因为我可以按引用序列化并按值反序列化,但是标头的存在使这变得不可能。我觉得我错过了一些关于 Serde 如何在这里借用数据的信息......