我知道错误的含义,但是我无法解决。我正在使用mockers
来测试我的工作,并且在尝试验证赋予模拟特征的函数的struct参数时遇到问题。简化代码:
#[cfg(test)]
extern crate mockers;
#[cfg(test)]
extern crate mockers_derive;
#[cfg(test)]
use mockers_derive::mocked;
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
pub struct Thing {
pub key: String,
pub class: String,
}
#[cfg_attr(test, mocked)]
pub trait DaoTrait {
fn get(&self, thing: &Thing) -> String;
}
struct DataService {
dao: Box<DaoTrait>,
}
impl DataService {
pub fn get(&self, thing: &Thing) -> String {
self.dao.get(thing)
}
}
#[cfg(test)]
mod test {
use super::*;
use mockers::matchers::eq;
use mockers::Scenario;
#[test]
fn my_test() {
use mockers::matchers::check;
let scenario = Scenario::new();
let mut dao = scenario.create_mock_for::<DaoTrait>();
let thing = Thing {
key: "my test".to_string(),
class: "for test".to_string(),
};
scenario.expect(
dao.get_call(check(|t: &Thing| t.to_owned() == thing))
.and_return("hello".to_string()),
);
let testee = DataService { dao: Box::new(dao) };
let rtn = testee.get(&thing);
assert_eq!(rtn, "hello");
}
}
我得到了错误:
warning: unused import: `mockers::matchers::eq`
--> src/main.rs:33:9
|
33 | use mockers::matchers::eq;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default
error[E0277]: can't compare `&Thing` with `Thing`
--> src/main.rs:47:57
|
47 | dao.get_call(check(|t: &Thing| t.to_owned() == thing))
| ^^ no implementation for `&Thing == Thing`
|
= help: the trait `std::cmp::PartialEq<Thing>` is not implemented for `&Thing`
error[E0277]: the trait bound `mockers::matchers::BoolFnMatchArg<Thing, [closure@src/main.rs:47:32: 47:65 thing:_]>: mockers::MatchArg<&Thing>` is not satisfied
--> src/main.rs:47:17
|
47 | dao.get_call(check(|t: &Thing| t.to_owned() == thing))
| ^^^^^^^^ the trait `mockers::MatchArg<&Thing>` is not implemented for `mockers::matchers::BoolFnMatchArg<Thing, [closure@src/main.rs:47:32: 47:65 thing:_]>`
|
= help: the following implementations were found:
<mockers::matchers::BoolFnMatchArg<T, F> as mockers::MatchArg<T>>
我查看了check
的源代码:
pub fn check<T, F: Fn(&T) -> bool>(f: F) -> BoolFnMatchArg<T, F> {
BoolFnMatchArg { func: f, _phantom: PhantomData }
}
我认为我给的闭包|t: &Thing| t.to_owned() == thing
是正确的。我也尝试了以下关闭,但没有一个起作用。
|t: &Thing| t == &thing
|t: &Thing| *t == thing
|t: Thing| t == thing
The Cargo.toml:
[dev-dependencies]
mockers = "0.12.1"
mockers_derive = "0.12.1"
答案 0 :(得分:2)
要注意的第一件事(双关语不是故意的)是t.to_owned()
产生&Thing
,而不是您可能期望的Thing
。这是因为Thing
没有实现Clone
,因此也没有实现ToOwned
(因为存在一个隐含的隐式实现,它为所有{{1} }类型),它提供了to_owned
方法。但是,为什么通话仍然有效?因为引用实现ToOwned
,所以Clone
实现Clone
!这给&Thing
签名:
ToOwned
您可以通过将to_owned
导出为fn to_owned(self: &&Thing) -> &Thing;
来解决此问题。
但是,您不需要 克隆Clone
来进行比较。您可以将两个引用与Thing
进行比较(例如,通过编写Thing
)。 PartialEq::eq
(Thing
运算符转换为该变量)通过引用获取其参数,并通过剥离一层引用来获取references implement PartialEq
(即它们不比较指针值,与原始指针不同)类型)。
答案 1 :(得分:2)
您无法使用Thing
的默认派生将&Thing
与PartialEq
进行比较:
#[derive(Debug, PartialEq)]
struct Thing(String);
fn main() {
let t_val = Thing(String::new());
let t_ref = &t_val;
t_val == t_ref;
}
error[E0308]: mismatched types
--> src/main.rs:8:14
|
8 | t_val == t_ref;
| ^^^^^ expected struct `Thing`, found &Thing
|
= note: expected type `Thing`
found type `&Thing`
要修复该错误,您需要执行以下两项操作之一:
匹配参考级别:
t_val == *t_ref
&t_val == t_ref
对引用数量不匹配的实现相等:
impl<'a> PartialEq<&'a Thing> for Thing {
fn eq(&self, other: &&'a Thing) -> bool {
self == *other
}
}
impl<'a> PartialEq<Thing> for &'a Thing {
fn eq(&self, other: &Thing) -> bool {
*self == other
}
}
但是,这些都不能解决您的实际问题。您误解了模仿者库的工作方式;您的闭包使用了错误的参考级别,并且需要对值的所有权进行比较:
let expected_thing = thing.clone();
scenario.expect(
dao.get_call(check(move |t: &&Thing| t == &&expected_thing))
.and_return("hello".to_string()),
);