Почему moq не использует этот параметр при настройке? - PullRequest
2 голосов
/ 08 ноября 2011

У меня есть этот тест

[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: следующие настройки не были сопоставлены:

ICachem => m.Add (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 Ответ

5 голосов
/ 08 ноября 2011

Когда вы используете Setup в Moq, вы говорите: «Возвращайте это, когда видите именно эти параметры».Для ссылочных типов, таких как Product, он будет работать только тогда, когда увидит именно этот экземпляр.Поэтому, когда Get запускается, он создает новый экземпляр Product для внутреннего использования и не соответствует вашему ожиданию от product1.

Как упоминал Крис, если вы вместо этого использовали It.IsAny<Product>() в программе установки, он будет соответствоватьновый экземпляр и работа как задумано.

...