Ho classe A
che sto testando un metodo su quell'unità che prende la classe B
come parametro. La classe B
è ciò che sto cercando di prendere in giro, ed è una classe astratta. La classe è simile al di sotto.Come si prende in giro una classe astratta contenente un metodo astratto interno usando Moq?
public abstract class B
{
internal abstract void DoSomething();
}
Il mio test di unità è simile.
[TestMethod]
public void ClassA_Add_TestSomething()
{
var classA = new A();
var mock = new Mock<B>();
classA.Add(mock.Object);
// Assertion
}
Ricevo la seguente eccezione.
Metodo TestSomething ha gettato un'eccezione:
System.ArgumentException: Tipo di deridere deve essere un'interfaccia o una classe astratta o non sigillati. ---> System.TypeLoadException: Metodo 'DoSomething' nel tipo 'Castle.Proxies.BProxy' dall'assembly 'DynamicProxyGenAssembly2, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null' non ha un'implementazione.
Posso aggirare questo rendendo il metodo virtuale anziché astratto, ma non è quello che voglio realizzare con il design dell'API. Ho anche provato a fornire un'implementazione attraverso mock.Setup(m => m.DoSomething())
senza alcun risultato. Questo è possibile con Moq, o dovrò creare una classe di test concreta che deriva dalla classe B astratta? Volevo evitare di creare tipi concreti, che tipo di sconfitte hanno lo scopo di usare una struttura di derisione o di stoppaggio, o sono fuorviato qui?
Modifica Ho scoperto che se faccio il metodo public abstract
questo problema non si verifica. Quindi immagino che la vera domanda sia se questo è possibile anche con un metodo interno quando si utilizza InternalsVisibleTo e Moq.
Perché non puoi usare mock.Setup? – brz
Ricevo l'eccezione se utilizzo l'installazione o meno. Nel mio test unitario, non mi importa se 'B.DoSomething' ha o no un'implementazione, anche se capisco perché ne avrebbe bisogno.È possibile che io non stia usando 'Setup' correttamente, ma ciò che ho provato era piuttosto semplice' mock.Setup (m => m.DoSomething()). Callback (() => {}); ' –
Considerare attentamente perché hai un metodo 'internal abstract' su una classe pubblica. Altri non saranno in grado di implementare il metodo astratto perché non è visibile a loro. Forse questo è quello che vuoi, anche se poi consiglierei di rendere anche i costruttori interni così nessuno ha l'idea di poter implementare la classe astratta. –