Mocking
Para mocking, Mockall Ă© uma biblioteca muito usada. VocĂȘ precisa refatorar seu cĂłdigo para usar traits, que vocĂȘ pode entĂŁo rapidamente "mockar":
use std::time::Duration;
#[mockall::automock]
pub trait Pet {
fn is_hungry(&self, since_last_meal: Duration) -> bool;
}
#[test]
fn test_robot_dog() {
let mut mock_dog = MockPet::new();
mock_dog.expect_is_hungry().return_const(true);
assert_eq!(mock_dog.is_hungry(Duration::from_secs(10)), true);
}
-
Mockall Ă© a biblioteca de mocking recomendada para Android (AOSP). Existem outras bibliotecas de mocking disponĂveis em crates.io, em particular na ĂĄrea de mocking de serviços HTTP. As outras bibliotecas de mocking funcionam de maneira semelhante ao Mockall, o que significa que elas facilitam a obtenção de uma implementação de mock de um determinado trait.
-
Observe que o mocking Ă© um tanto controverso: mocks permitem que vocĂȘ isole completamente um teste de suas dependĂȘncias. O resultado imediato Ă© uma execução de teste mais rĂĄpida e estĂĄvel. Por outro lado, os mocks podem ser configurados incorretamente e retornar uma saĂda diferente daquela que as dependĂȘncias reais fariam.
Se possĂvel, Ă© recomendĂĄvel que vocĂȘ use as dependĂȘncias reais. Como exemplo, muitos bancos de dados permitem que vocĂȘ configure um backend em memĂłria. Isso significa que vocĂȘ obtĂ©m o comportamento correto em seus testes, alĂ©m de serem rĂĄpidos e limparem automaticamente apĂłs si mesmos.
Da mesma forma, muitos frameworks da web permitem que vocĂȘ inicie um servidor em processo que se vincula a uma porta aleatĂłria em
localhost
. Sempre prefira isso a mockar o framework pois isso ajuda vocĂȘ a testar seu cĂłdigo no ambiente real. -
Mockall nĂŁo faz parte do playground do Rust, entĂŁo vocĂȘ precisa executar este exemplo em um ambiente local. Use
cargo add mockall
para adicionar rapidamente o Mockall a um projeto Cargo existente. -
Mockall tem muito mais funcionalidades. Em particular, vocĂȘ pode configurar expectativas que dependem dos argumentos passados. Aqui usamos isso para "mockar" um gato que fica com fome 3 horas apĂłs a Ășltima vez que foi
#[test]
fn test_robot_cat() {
let mut mock_cat = MockPet::new();
mock_cat
.expect_is_hungry()
.with(mockall::predicate::gt(Duration::from_secs(3 * 3600)))
.return_const(true);
mock_cat.expect_is_hungry().return_const(false);
assert_eq!(mock_cat.is_hungry(Duration::from_secs(1 * 3600)), false);
assert_eq!(mock_cat.is_hungry(Duration::from_secs(5 * 3600)), true);
}
- VocĂȘ pode usar
.times(n)
para limitar o nĂșmero de vezes que um mĂ©todo mock pode ser chamado paran
--- o mock automaticamente irĂĄ gerar um pĂąnico quando descartado se isso nĂŁo for satisfeito.