¿Por qué moq no usa este parámetro en su configuración?

I have this test

[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();
}

Obtengo esta excepción

Moq.MockVerificationException: The following setups were not matched:

ICache m => m.Add(1, )

The invocation contains the second parameter but why does moq not recognize it during setup? It works, when i omit the setup for .Add!?


Noticias This is the code that is executed

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);
}

preguntado el 08 de noviembre de 11 a las 16:11

You might be better off using the It.IsAny<TYPE> instead of explicit arguments -

1 Respuestas

When you use Setup in Moq, you're saying "Return this when you see exactly these parameters". For reference types like Product, it will only work when it sees that exact instance. So when Get runs, it's creating a new Product instance internally and is not matching your expectation from product1.

As Chris mentioned, if you used It.IsAny<Product>() in the Setup instead, it would match the new instance and work as intended.

respondido 08 nov., 11:21

I tried this this.cacheMock.Setup(m => m.Add(key, It.IsAny<IProduct>())).Returns(product1); but i does not work - mrt181

Have you tried debugging and figuring out if it's trying to call Add and with what parameters? - RandomEngy

Yes, i debugged the code and it calls Add but then I saw your phrase "...when you see exactly these parameters". My Setup uses 1 as key, but the real code uses product.GetHashCode() as key. That was the problem. var key = product1.GetHashCode(); this.cacheMock.Setup(m => m.Add(key, It.IsAny<IProduct>())).Returns(null as IProduct); - mrt181

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.