use unimock::*;
#[unimock(api=SingleArgMock)]
trait SingleArg {
fn method1<'s>(&'s self, a: &'s str) -> &'s str;
}
#[test]
#[should_panic(expected = "SingleArg::method1(\"hoi\"): No mock implementation found.")]
fn should_panic_for_nonexisting_mock() {
Unimock::new(()).method1("hoi");
}
#[test]
#[should_panic(
expected = "Mock for SingleArg::method1 was never called. Dead mocks should be removed."
)]
fn should_panic_for_unused_stub() {
Unimock::new(SingleArgMock::method1.stub(|each| {
each.call(matching!(_));
}));
}
#[test]
#[should_panic(
expected = "A clause for SingleArg::method1 has already been registered as InAnyOrder, but got re-registered as InOrder. They cannot be mixed for the same MockFn."
)]
fn should_complain_about_mismatched_modes() {
Unimock::new((
SingleArgMock::method1.each_call(matching!(_)).returns("a"),
SingleArgMock::method1
.next_call(matching!(_))
.returns("b")
.once(),
));
}
#[test]
#[should_panic(expected = "Stub contained no call patterns")]
fn should_panic_for_empty_stub_closure() {
let _ = Unimock::new(SingleArgMock::method1.stub(|_| {}));
}
#[test]
#[should_panic(
expected = "SingleArg::method1(\"whatever\"): No output available for after matching SingleArg::method1(_) at tests/it/errors.rs:50."
)]
fn call_pattern_without_output_factory_should_crash() {
Unimock::new(SingleArgMock::method1.stub(|each| {
each.call(matching!(_));
}))
.method1("whatever");
}
#[test]
#[should_panic(expected = "SingleArg::method1(\"anything\"): No matching call patterns.")]
fn should_panic_if_no_call_patterns_in_stub_are_matched() {
Unimock::new(SingleArgMock::method1.stub(|each| {
each.call(matching!("something"));
}))
.method1("anything");
}
#[test]
#[should_panic(
expected = "SingleArg::method1: Expected SingleArg::method1(\"a\") at tests/it/errors.rs:70 to match exactly 1 call, but it actually matched no calls."
)]
fn call_pattern_with_count_expectation_should_panic_if_not_met() {
Unimock::new(SingleArgMock::method1.stub(|each| {
each.call(matching!("a")).returns(String::new()).once();
each.call(matching!(_)).returns(String::new());
}))
.method1("b");
}
#[test]
#[should_panic(
expected = "SingleArg::method1(\"b\"): Explicit panic from SingleArg::method1(_) at tests/it/errors.rs:82: foobar!"
)]
fn should_panic_with_explicit_message() {
Unimock::new(SingleArgMock::method1.stub(|each| {
each.call(matching!(_)).panics("foobar!");
}))
.method1("b");
}
#[test]
#[should_panic(
expected = "Unimock cannot verify calls, because the original instance got dropped while there are clones still alive."
)]
fn should_crash_when_the_original_instance_disappears_before_the_clone() {
let _ = {
let original = Unimock::new(());
let clone = original.clone();
drop(original);
clone
};
}
#[test]
#[should_panic(expected = "SingleArg::method1(\"\"): No mock implementation found.")]
fn multithread_error_reporting_works() {
let unimock = Unimock::new(());
#[allow(clippy::redundant_clone)]
let clone = unimock.clone();
std::thread::spawn(move || {
clone.method1("");
})
.join()
.expect_err("");
}
#[test]
#[should_panic(
expected = "Foo::foo(2): Cannot return value more than once from Foo::foo(_) at tests/it/errors.rs:125, because of missing Clone bound. Try using `.each_call()` or explicitly quantifying the response."
)]
fn should_complain_when_returning_unquantified_value_more_then_once() {
#[unimock(api=FooMock)]
trait Foo {
fn foo(&self, arg: i32) -> i32;
}
let unimock = Unimock::new(FooMock::foo.some_call(matching!(_)).returns(42));
assert_eq!(42, unimock.foo(1));
unimock.foo(2);
}
#[test]
#[should_panic(
expected = "Foo::foo: Expected Foo::foo(2) at tests/it/errors.rs:143 to match exactly 1 call, but it actually matched no calls."
)]
fn should_require_both_calls_2_some_call() {
#[unimock(api=FooMock)]
trait Foo {
fn foo(&self, arg: i32) -> i32;
}
let unimock = Unimock::new((
FooMock::foo.some_call(matching!(1)).returns(42),
FooMock::foo.some_call(matching!(2)).returns(1337),
));
assert_eq!(42, unimock.foo(1));
}
#[test]
#[should_panic(
expected = "Original Unimock instance destroyed on a different thread than the one it was created on. To solve this, clone the object before sending it to the other thread."
)]
fn should_crash_when_sending_original_unimock_to_another_thread() {
let u = Unimock::new(());
let drop_u = move || drop(u);
let err = std::thread::spawn(drop_u).join().expect_err("Must error");
std::panic::resume_unwind(err);
}
#[test]
#[should_panic(
expected = "SingleArg::method1(\"\"): No function supplied for matching inputs for call pattern SingleArg::method1[#0]."
)]
fn no_matcher_function() {
let u = Unimock::new(SingleArgMock::method1.next_call(&|_| ()).returns(""));
u.method1("");
}