2010-09-08 8 views
12

ho aggiunto un'interfaccia covariante al nostro progetto:errore di generazione in progetto di test di unità con funzioni di accesso di un progetto contenente tipi covarianti

interface IView 
{ 
} 

interface IPresenter<out TView> where TView : IView 
{ 
    TView View { get; } 
} 

ho creato alcune classi, di attuazione di queste interfacce:

class TestView : IView 
{ 
} 

class TestPresenter : IPresenter<TestView> 
{ 
    public TestView View 
    { 
    get { return something; } 
    } 

    private void DoSomething() 
    { 
    } 
} 

E Posso usare questo senza problemi:

IPresenter<IView> presenter = new TestPresenter(); 

Quindi tutto sembra giusto, quindi presumo la mia c l'utilizzo dell'ovarianza è corretto. Sfortunatamente i nostri progetti di test unitari contengono accessor privati ​​di alcuni tipi che si trovano nello stesso progetto come l'interfaccia covariante, che causa un errore di compilazione.

Could not load type 'GenericInheritanceTest.IPresenter_Impl`1' from assembly 'GenericInheritanceTest_Accessor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it declares a covariant or contravariant type parameter and is not an interface or delegate.

Qual è esattamente il problema qui? C'è un fallimento nella mia implementazione, resp. come risolvere questo? Non può essere, che dobbiamo evitare gli accessor non appena usiamo i tipi covarianti ??? È possibile impedire la creazione di accessor per determinati tipi per risolvere questo problema?

+0

È consigliabile evitare accessorie private in generale, poiché causano un accoppiamento troppo stretto tra test e codice di produzione. – Grzenio

+0

Sì, grazie, ma ho qui un progetto già esistente con 120k loc e un buon utilizzo di accessor privati, quindi non sarà solo un polpastrello per rielaborarlo. – Enyra

risposta

12

Questo è un bug in Visual Studio 2010. È stato segnalato a Microsoft Connect ma è stato chiuso e apparentemente non verrà risolto.

In base a un post di Bruce Taimana, lo sviluppo di the private accessor feature è stato interrotto e potrebbe essere rimosso nelle versioni future di Visual Studio. Possibili alternative elencate sono:

  1. Use the Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject class to assist in accessing internal and private APIs in your code. This is found in the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll assembly.

  2. Create a reflection framework that would be able to reflect off your code to access internal or private APIs.

  3. If the code you are trying to access is internal, you may be able to access your APIs using the InternalsVisibleToAttribute so your test code can have access to the internal APIs.

+3

Una risposta tardiva ma grazie :) Sì, gli accessor privati ​​sono deprecati, nel frattempo mentre abbiamo rimosso tutti gli accessor privati ​​nel nostro progetto. Dalla tua lista di soluzioni preferisco il punto 4. Migliora la testabilità con una buona struttura dell'oggetto (IoC) :) – Enyra

0

ero alle prese con questo errore e anche ottenuto un errore: Il "BuildShadowTask" Errore imprevisto. L'unico modo per eliminare l'errore quando ho provato a risolverlo qui è rimuovere la parola chiave out dai generici, ad esempio un'interfaccia covariante.

In realtà ho ottenuto questo errore quando ReSharper mi ha suggerito che tipo di parametro potrebbe essere covariante:

private delegate TResult Action<TResult>(); 

cambiato in:

private delegate TResult Action<out TResult>(); 

Purtroppo, ho dovuto cambiare di nuovo di nuovo e la disattivazione del Avvertenza di rilarzo in un commento:

// ReSharper disable once TypeParameterCanBeVariant 
private delegate TResult Action<TResult>(); 

Una strategia può quindi essere quella di scottare ch per:

"<out" 

in un progetto e rimuovere la parola chiave out, solo per farlo compilare. Non molto elegante, ma non molto elegante anche da Microsoft, perché lo è stato rapportato cinque anni fa tramite Microsoft Connect e hanno scelto di risolvere il problema solo con lo . Il problema è nei progetti di test unitari. Non aiuta a cambiare da Visual Studio Unit Testing Framework a NUnit Testing Framework.

0

Se si utilizza Unity Intercetttion e il proprio parametro è etichettato come fuori, Unity Intercottion causerà questo errore. La ragione di ciò è che Intercettazione deve essere in grado di leggere l'elenco dei parametri. Così simile al caso precedente, se Resharper avverte che il parametro può essere covariante, questo avviso deve essere ignorato.

Problemi correlati