#c# #tdd #mocking #moq
#c# #tdd #издевательство #moq
Вопрос:
У меня есть этот тест
[Fact]
public void Get_if_item_is_not_in_cache_return_null_returns_true()
{
var repo = new Repository<IProduct>(
this.factoryMock.Object,
this.cacheMock.Object,
this.readerMock.Object,
this.storageMock.Object);
var key = 1;
const string Name = "Product1";
var date = new DateTime(0, DateTimeKind.Utc);
var product1 = this.Product; /* returns new Product(
* "Product1",
* new DateTime(0, DateTimeKind.Utc),
* new Dictionary<string, decimal>
* { { "@1lom", 0m }, { "@2lom", 0m } }) */
this.cacheMock.Setup(
m => m.Add(key, product1)).Returns(product1);
this.cacheMock.Setup(
m => m.Get<IList<IDictionary<string, object>>>(0)).Returns(null as IList<IDictionary<string, object>>);
this.cacheMock.Setup(
m => m.Get<IProduct>(key)).Returns(null as IProduct);
this.factoryMock.Setup(
m => m.Create(
Name,
date,
this.cacheMock.Object.Get<IList<IDictionary<string, object>>>(0))).Returns(product1);
var product2 = repo.Get(key, Name, date);
Assert.Null(product2);
this.cacheMock.VerifyAll();
this.factoryMock.VerifyAll();
}
Я получаю это исключение
Исключение Moq.MockVerificationException: следующие настройки не были сопоставлены:
ICache m => m.Добавить(1, )
Вызов содержит второй параметр, но почему moq не распознает его во время настройки? Это работает, когда я опускаю настройку для .Add!?
Обновить Это код, который выполняется
public virtual T Get(int key, string productName, DateTime date)
{
return this.Cache.Get<T>(key) ?? this.PersistenStorage.Query(productName, date) ?? this.CreateNewCacheItem(productName, date);
}
protected virtual T CreateNewCacheItem(string productName, DateTime date)
{
var product = this.Factory.Create(productName, date, this.Cache.Get<IList<IDictionary<string, object>>>(this.RawDataKey));
return this.Cache.Add(product.GetHashCode(), product);
}
Комментарии:
1. Возможно, вам было бы лучше использовать It. Есть какой-либо <ТИП> вместо явных аргументов
Ответ №1:
Когда вы используете Setup в Moq, вы говорите «Верните это, когда увидите именно эти параметры». Для ссылочных типов, таких как Product
, он будет работать только тогда, когда увидит этот точный экземпляр. Итак, когда запускается Get, он создает новый Product
экземпляр внутренне и не соответствует вашим ожиданиям от product1
.
Как упоминал Крис, если бы вместо этого вы использовали It.IsAny<Product>()
в настройке, он соответствовал бы новому экземпляру и работал по назначению.
Комментарии:
1. Я попробовал это this.cacheMock. Setup(m => m.Добавить(ключ, Это. IsAny<IProduct>())).Возвращает(product1); но i не работает
2. Вы пробовали отлаживать и выяснять, пытается ли он вызвать
Add
и с какими параметрами?3. Да, я отладил код, и он вызывает Add, но затем я увидел вашу фразу «… когда вы видите именно эти параметры». Моя настройка использует 1 в качестве ключа, но реальный код использует product. GetHashCode() в качестве ключа. В этом и заключалась проблема. var key = product1. GetHashCode(); this.cacheMock. Setup(m => m.Добавить(ключ, Это. IsAny<IProduct>())).Возвращает(null как IProduct);