2012-11-20 1 views
5

Sto cercando di capire questa ginnastica Moq per le ultime ore. Ho le seguenti classi - e sto provando a fare una verifica un po 'semplice e sta fallendo - e non riesco a capire perché.Verifica moq nidificata

Avviso durante l'installazione di Moq, restituisco un Mock.Of quando viene richiesto BeginCounter - ma quando provo a verificarlo fallisce. Tuttavia, se disapprovo la riga p.Setup (e => e.BeginCounter.Increment()) la verifica funziona.

Cosa mi manca?

public interface IPerformanceCounters 
{ 
    void Increment(); 
    void Decrement(); 
} 

public interface IContext 
{ 
    IPerformanceCounters BeginCounter { get; } 
} 

public class Test 
{ 
    private readonly IContext context; 
    public Test(IContext context) { this.context = context; } 
    public void React() { this.context.BeginCounter.Increment(); } 
} 

void Test() 
{ 
    // ARRANGE 
    var p = new Mock<IContext>(); 
    p.Setup(e => e.BeginCounter).Returns(() => Mock.Of<IPerformanceCounters>()); // This does not work 
    // p.Setup(e => e.BeginCounter.Increment()); // However, this works! 

    // ACT 
    var test = new Test(p.Object); 
    test.React(); 

    // ASSERT 
    p.Verify(v => v.BeginCounter.Increment(), Times.Once()); 
} 

risposta

3

Credo che questo è perché un metodo non-setup non è verificabile.

Per quanto posso dire, si sta restituendo una simulazione e quindi si tenta di verificare contro di essa. Ma non è preparato fino a quando non decommentate il setup.

void Test() 
{ 
    // ARRANGE 
    var p = new Mock<IContext>(); 
    var perfCountMock = new Mock<IPerformanceCounters>(); 
    p.Setup(e => e.BeginCounter).Returns(() => perfCountMock.Object); // This does not work 
    perfCountMock.Setup(e => e.Increment()); 

    // ACT 
    var test = new Test(p.Object); 
    test.React(); 

    // ASSERT 
    perfCountMock.Verify(v => v.Increment(), Times.Once()); 
} 

Quanto sopra è quello che stai realmente facendo. Non stai verificando la chiamata IContext, ma invece la chiamata IPerformanceCounters. Lo configurerei in questo modo in modo che sia più facile da capire, ma potresti facilmente decommentare la riga

Se vuoi lasciarlo così com'è, devi capire meglio la funzionalità Mock.Of.

void Test() 
{ 
     // ARRANGE 
     var p = new Mock<IContext>(); 
     var mockOfPerf = Mock.Of<IPerformanceCounters>(); 
     p.Setup(e => e.BeginCounter).Returns(mockOfPerf); // This does not work 

     // ACT 
     var test = new Test1(p.Object); 
     test.React(); 

        // ASSERT 
     Mock.Get(mockOfPerf).Verify(v=>v.Increment(), Times.Once()); 
} 

Questa è la stessa cosa come sopra, usando solo le funzionalità dei Mock.Of. Non è possibile verificare i mock nidificati, è necessario verificare l'effettivo simulato

+0

Non penso che questa affermazione "metodo non di installazione non verificabile" sia vera. Ecco perché. Se aggiungo un metodo in IContext, posso verificarlo senza una configurazione. È la natura annidata di IContext> IPerformanceCounters che sta causando un problema che non riesco a capire. – splusq

+1

Ho appena aggiornato la mia risposta. Speriamo, questo ha più senso. Nel peggiore dei casi è possibile scavare nel codice in quanto è open source –

+0

grazie - Mock.Get è un bel trucco. – splusq