2010-09-08 2 views
12

he añadido una interfaz covariante a nuestro proyecto:fracaso de construcción en el proyecto de prueba de unidad con descriptores de acceso de un proyecto que contiene tipos covariantes

interface IView 
{ 
} 

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

creé algunas clases, la implementación de estas interfaces:

class TestView : IView 
{ 
} 

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

    private void DoSomething() 
    { 
    } 
} 

Y Puedo usar esto sin problemas:

IPresenter<IView> presenter = new TestPresenter(); 

Así que todo parece correcto, así que supongo que mi c el uso de la variación es correcto. Lamentablemente, nuestros proyectos de prueba unitaria contienen accesos privados de algunos tipos ubicados en el mismo proyecto, como la interfaz covariante, que causa un error de compilación.

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.

¿Cuál es exactamente el problema aquí? ¿Hay alguna falla en mi implementación, resp. ¿Cómo arreglar esto? ¿No puede ser que tengamos que evitar los accesadores tan pronto como usemos tipos covariantes? ¿Es posible evitar la creación de accesadores para ciertos tipos para resolver este problema?

+0

Debe evitar los accesadores privados en general, ya que causan un acoplamiento demasiado apretado entre las pruebas y el código de producción. – Grzenio

+0

Sí, gracias, pero tengo aquí un proyecto ya existente con 120k loc y un buen uso de accesadores privados, por lo que no será solo una yema del dedo para volver a trabajarlo. – Enyra

Respuesta

12

Se trata de un error en Visual Studio 2010. Se ha notificado que es Microsoft Connect pero se ha cerrado y, aparentemente, no se solucionará.

Según una entrada de blog de Bruce Taimana, el desarrollo de the private accessor feature ha sido detenido y puede ser eliminado en versiones futuras de Visual Studio. Posibles alternativas enumeradas son:

  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 respuesta tardía, pero gracias :) Sí, los accesorios privados están en desuso, mientras retiramos todos los accesorios privados en nuestro proyecto. De su lista de soluciones, prefiero el punto 4. Mejorar la capacidad de prueba con una buena estructura de objetos (IoC) :) – Enyra

0

he tenido problemas con este error y también da un error: El "BuildShadowTask" error inesperado. La única forma de deshacerse del error cuando intenté resolverlo aquí es eliminar la palabra clave out de los genéricos, es decir, una interfaz covariante.

realidad tiene este error cuando ReSharper me sugirió que el parámetro de tipo podría ser covariante:

private delegate TResult Action<TResult>(); 

cambiado a:

private delegate TResult Action<out TResult>(); 

Lamentablemente, tuve que cambiarlo de nuevo otra vez y la desactivación de la Advertencia de Resharper en un comentario:

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

Por lo tanto, una estrategia puede ser buscar ch para:

"<out" 

en un proyecto y elimine la palabra clave out, solo para compilarla. No muy elegante, pero no muy elegante por parte de Microsoft, porque esto se debatió hace cinco años a través de Microsoft Connect y ellos han elegido simplemente cerrar el problema. El problema está en Proyectos de prueba de unidad. No ayuda a cambiar de Visual Studio Unit Testing Framework a NUnit Testing Framework.

0

Si está utilizando la intercepción de Unity y su parámetro está etiquetado como out, la intercepción de Unity causará este error. La razón de esto es que Interception debe poder leer la lista de parámetros. De manera similar al caso anterior, si Resharper advierte que el parámetro puede ser covariante, esta advertencia debe ignorarse.

Cuestiones relacionadas