Я думаю, что @Nkosi имеет правильный ответ для демонстрации использования библиотеки для насмешек.В ветке комментариев по этому вопросу меня попросили привести пример использования тестовой реализации, а не библиотеки-насмешки.Итак, вот с оговоркой из ветки комментариев, что IMongoQueryable<Auto> GetQueryable()
не подходит для интерфейса, не зависящего от постоянства, и поэтому мы можем удалить его или заменить его на IQueryable
или другой адаптер.
ТамЕсть много способов сделать это.Я использовал список поддержки (мог также использовать словарь / карту с ключом по идентификатору) для реализации версии в памяти IAutoDb
: (Отказ от ответственности: черновик. Пожалуйста, просмотрите и протестируйте, прежде чем использовать это где-либо)
class TestAutoDb : IAutoDb
{
public List<Auto> Autos = new List<Auto>();
public Task<Auto> Create(Auto auto) {
Autos.Add(auto);
return Task.FromResult(auto);
}
public Task<Auto> Get(Guid id) => Task.Run(() => Autos.Find(x => x.Id == id));
public Task<List<Auto>> GetAll() => Task.FromResult(Autos);
public Task Remove(Auto model) => Task.Run(() => Autos.Remove(model));
public Task Remove(Guid id) => Task.Run(() => Autos.RemoveAll(x => x.Id == id));
public Task Update(Guid id, Auto model) => Remove(id).ContinueWith(_ => Create(model));
}
Теперь мы можем тестировать по известным состояниям находящейся в памяти базы данных:
[Fact]
public async Task Get3Autos() {
var db = new TestAutoDb();
// Add 3 autos
var firstGuid = new Guid(1, 2, 3, new byte[] { 4, 5, 6, 7, 8, 9, 10, 11 });
db.Autos = new List<Auto> {
new Auto { Id = firstGuid, Name = "Abc" },
new Auto { Id = Guid.NewGuid(), Name = "Def" },
new Auto { Id = Guid.NewGuid(), Name = "Ghi" }
};
var service = new AutoService(db);
// Check service layer (note: just delegates to IAutoDb, so not a very useful test)
var result = await service.GetAutoById(firstGuid);
Assert.Equal(db.Autos[0], result);
}
Я думаю, что ручная реализация таких тестовых классов - хороший способ начатьс тестированием, а не прыгать прямо в издевательскую библиотекуБиблиотеки-насмешки автоматизируют создание этих классов тестов и немного упрощают изменение поведения для каждого теста (например, вызов Get
возвращает невыполненную задачу для имитации сетевой ошибки или аналогичной), но вы также можете сделать этовручную.Если вам скучно делать это вручную, то сейчас самое время обратиться к библиотеке для насмешек, чтобы сделать это проще.:)
Есть также преимущества, позволяющие полностью избежать насмешливых библиотек.Возможно, проще иметь явно реализованный тестовый класс, команде не нужно изучать новую библиотеку, удобно повторно использовать ее в нескольких тестах и приспособлениях (возможно, используя ее также для тестирования более сложных сценариев интеграции), и можетдаже потенциально может использоваться в самом приложении (например: для предоставления демонстрационного режима или аналогичного).
Из-за природы этого конкретного интерфейса (его участники имеют подразумеваемые контракты между ними: вызов create и затем получение этогоid должен возвращать только что созданный экземпляр). В этом случае я бы склонялся к использованию явного тестового класса, чтобы гарантировать соблюдение этих контрактов.Для меня насмешка наиболее полезна, когда меня не волнуют эти контракты, мне просто нужно знать, что был вызван определенный член, или что, когда другой член возвращает определенный результат, мой класс действует ожидаемым образом.