[매주 1라이브러리] - Mockall의 강력한 Rust 대상 시뮬레이션 라이브러리(4부분-완결)
이번이 Mockall 시리즈의 마지막 편이다.
연관 유형
연관 유형을 포함하는 피쳐도 시뮬레이션할 수 있습니다.일반 피쳐와 달리 시뮬레이션된 구조는 일반 구조가 아니므로 시뮬레이션 구조를 정의할 때 연관된 유형을 지정해야 합니다
#[automock\]
. 속성의 메타 항목을 통해 다음 작업을 수행할 수 있습니다.#[automock(type Key=u16; type Value=i32;)]
pub trait A {
type Key;
type Value;
fn foo(&self, k: Self::Key) -> Self::Value;
}
let mut mock = MockA::new();
mock.expect_foo()
.returning(|x: u16| i32::from(x));
assert_eq!(4, mock.foo(4));
다중 피쳐 및 상속 피쳐
여러 피쳐를 구현할 수 있는 아날로그 구조를 생성할 때 상속이 있든 없든
mock!
매크로를 사용해야 합니다.그러나 만들어진 후에 시뮬레이션 대상의 사용 방법은 다름없다.pub trait A {
fn foo(&self);
}
pub trait B: A {
fn bar(&self);
}
mock! {
//
C {}
// C
trait A {
fn foo(&self);
}
// C
trait B: A {
fn bar(&self);
}
}
let mut mock = MockC::new();
mock.expect_foo().returning(|| ());
mock.expect_bar().returning(|| ());
mock.foo();
mock.bar();
외부 피쳐
Mockall은 당신이 제어하지 않은 외부 패키지에서 정의한 특징과 구조형을 모의할 수 있지만,
mock!
매크로가 아니라 #[automock\]
를 사용해야 합니다.이렇게 외부 피쳐를 시뮬레이션할 수 있습니다.mock! {
MyStruct {} // , "Mock"
trait Clone { //
fn clone(&self) -> Self;
}
}
let mut mock1 = MockMyStruct::new();
let mock2 = MockMyStruct::new();
mock1.expect_clone()
.return_once(move || mock2);
let cloned = mock1.clone();
정적 방법
Mockall은 정적 방법을 시뮬레이션할 수도 있지만 주의해야 할 것은정적 방법을 시뮬레이션할 때 기대는 전역적입니다. 여러 테스트에서 정적 방법을 사용하려면 동기화를 제공해야 합니다. 일반적인 방법에서는 기대를 시뮬레이션 대상 위에 설정합니다. 그러나 정적 방법에 대응하는 시뮬레이션 대상이 없기 때문에 '언어 환경' 대상을 만들어서 기대를 설정해야 합니다.
#[automock]
pub trait A {
fn foo() -> u32;
}
let ctx = MockA::foo_context();
ctx.expect().returning(|| 99);
assert_eq!(99, MockA::foo());
하나의 상용 모델은 구조 방법으로 하나의 특징을 모의하는 것이다.이런 상황에서 너는 구조 방법을 이용하여 시뮬레이션 대상을 되돌릴 수 있다.
struct Foo{}
#[automock]
impl Foo {
fn from_i32(x: i32) -> Self {
// ...
}
fn foo(&self) -> i32 {
// ...
}
}
let ctx = MockFoo::from_i32_context();
ctx.expect()
.returning(|x| {
let mut mock = MockFoo::default();
mock.expect_foo()
.return_const(x);
mock
});
let foo = MockFoo::from_i32(42);
assert_eq!(42, foo.foo());
공통 정적 방법
통용되는 구조형이나 특징적인 정적 방법을 모의할 때 방법 자체가 통용되든 안 되든 틈이 없이 운행할 수 있다.
#[automock]
trait Foo {
fn new(t: T) -> MockFoo;
}
let ctx = MockFoo::::new_context();
ctx.expect()
.returning(|_| MockFoo::default());
let mock = MockFoo::::new(42u32);
어경 검사점
언어 환경의 대상이 작용역을 떠날 때 모든 기대는 비워집니다.언어 환경 대상은 다른 시뮬레이션 대상과 마찬가지로
checkpoint
방법이 있다.#[automock]
pub trait A {
fn foo() -> u32;
}
let ctx = MockA::foo_context();
ctx.expect()
.times(1)
.returning(|| 99);
ctx.checkpoint(); // Panics!
시뮬레이션 대상의 검사점 방법은 정적 방법에 대해 검사를 진행하지 않는다.이 동작은 여러 시뮬레이션 객체를 동시에 사용하는 데 유용합니다. 예를 들면 다음과 같습니다.
#[automock]
pub trait A {
fn build() -> Self;
fn bar(&self) -> i32;
}
let ctx = MockA::build_context();
ctx.expect()
.times(2)
.returning(|| MockA::default());
let mut mock0 = MockA::build();
mock0.expect_bar().return_const(4);
mock0.bar();
mock0.checkpoint(); // build checkpoint
let mock1 = MockA::build();
또 하나 주의해야 할 것은 Mockall은 일반적인 상황에서 모든 아날로그 구조형에 매개 변수가 없는
new
방법을 만들 것이다.그러나 new
라는 방법이 포함된 구조형을 시뮬레이션할 때, Mockall은 자동으로 만들어지지 않습니다.외부 방정식
Mockall은 외부 방정식을 시뮬레이션할 수도 있습니다.정적 방법과 마찬가지로 외부 방정식을 모의할 때의 기대는 전역적이다.아날로그 구조형과 유사하게 아날로그 방정식을 접근할 수 있도록 가져오기에 대한 특별한 디버깅이 필요합니다.관련 유형과 마찬가지로
#[automock\]
속성에 추가 정보를 제공하여 외부 방정식을 시뮬레이션해야만 정상적으로 사용할 수 있다.mod ffi {
use mockall::automock;
#[automock(mod mock;)]
extern "C" {
pub fn foo(x: u32) -> i64;
}
}
cfg_if! {
if #[cfg(test)] {
use self::ffi::mock::foo;
} else {
use self::ffi::foo;
}
}
fn do_stuff() -> i64 {
unsafe{ foo(42) }
}
#[cfg(test)]
mod t {
use super::*;
#[test]
fn test_foo() {
let ctx = ffi::mock::foo_context();
ctx.expect()
.returning(|x| i64::from(x + 1));
assert_eq!(43, do_stuff());
}
}
모듈
외부 방정식을 시뮬레이션할 수 있는 것 이외에 Mockall은 모든 Rust 방정식의 모듈에 시뮬레이션을 파생시킬 수 있습니다. 이 기능은 매일 구축 기능을 사용해야 하고 가방에서 사용해야 합니다.
feature(proc_macro_hygiene)
사용 방법은 외부 기능을 시뮬레이션하는 것과 같지만 시뮬레이션 모듈의 명칭은 자동으로 생성된다.#![feature(proc_macro_hygiene)]
mod outer {
use mockall::automock;
#[automock()]
pub(super) mod inner {
pub fn bar(x: u32) -> i64 {
// ...
}
}
}
cfg_if! {
if #[cfg(test)] {
use outer::mock_inner as inner;
} else {
use outer::inner;
}
}
#[cfg(test)]
mod t {
use super::*;
#[test]
fn test_foo_bar() {
let ctx = inner::bar_context();
ctx.expect()
.returning(|x| i64::from(x + 1));
assert_eq!(5, inner::bar(4));
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.