2015-09-24 25 views
28

Utilizzo Visual Studio 2015 Enterprise RTM per scrivere test di unità per un progetto che utilizza Unity Container.Visual Studio 2015 InvalidProgramException in Unit Test con Fakes

ho scoperto che il semplice atto di aggiunta di un gruppo di falsi per l'unità, nemmeno in realtà utilizzando il falso, è sufficiente a generare questa eccezione:

System.InvalidProgramException: Common Language Runtime rilevato un programma non valido.



considerare i seguenti passaggi per riprodurre:

  • Utilizzando Visual Studio 2015 Enterprise RTM creare un progetto di prova Unità di mira .NET 4.6

  • Aggiungere il pacchetto NuGet "Unità" versione 3.5.1404.0

  • Aggiungere il pacchetto NuGet "CommonServiceLocator" versione 1.2.0

  • Scrivi un singolo test di unità in questo modo:

[TestClass] 
public class UnitTest1 : IDisposable 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     new ResolvedArrayParameter<IDisposable>(new IDisposable[] {this}); 
    } 

    void IDisposable.Dispose() 
    { 
    } 
} 
  • Verificare il test viene superato

  • Fare clic destro sul Microsoft.Practices.Unity di riferimento e scegliere " Aggiungi gruppo di falsi "

  • nuovamente eseguire il test

  • osservare le seguenti notevole fallimento del test:

Nome test: TestMethod1
prova FullName: UnitTestProject11.UnitTest1.TestMethod1
Fonte prova: c: \ temp \ UnitTestProject11 \ UnitTestProject11 \ UnitTest1.cs: linea 12
test Risultato: Impossibile
prova Durata: 0: 00: 00,0572447

StackTrace

Risultato:

a Microsoft.Practices.Unity.ResolvedArrayParameter..ctor (tipo arrayParameterType, Tipo elementType, oggetto [elementValues])
a Microsoft.Practices.Unity.ResolvedArrayParameter`1..ctor (Object [ ] elementValues)
a UnitTestProject11.UnitTest1.TestMethod1() in c: \ temp \ UnitTestProject11 \ UnitTestProject11 \ UnitTest1.cs: linea messaggio Risultato 13
:
metodo di prova UnitTestProject11.UnitTest1.TestMethod1 gettato un'eccezione:
sistema. InvalidProgramException: Common Language Runtime ha rilevato un programma non valido.



La caratteristica più straordinaria di questo problema è evidentemente falsi non hanno nemmeno bisogno di apparire direttamente nel codice per il fallimento di manifestare.

una vasta quantità di giocherellare rivela che retargeting il progetto di test per .NET 4.5 "correzioni" il problema, che è un non-starter per me, perché di another problema Ho pubblicato alcune settimane fa.

Ancora più giocherellando con praticamente tutte le impostazioni dei falsi (contratti di codice, ecc.) Non ha prodotto alcuna soluzione.

Qualsiasi consiglio su questo argomento sarebbe molto apprezzato.

+0

Avvia una taglia, perché incontriamo lo stesso 'InvalidProgramException' quando usiamo' ShimLocalPrintServer.Constructor ... 'per testare un metodo che istanzia un' System.Printing.LocalPrintServer'. Un 'UnityContainer' non è necessario per riprodurre questo errore. E il ripristino del framework non ha aiutato. L'eccezione viene sollevata quando il metodo testato chiama 'new LocalPrintServer (nuova stringa [0], PrintSystemDesiredAccess.EnumerateServer);' –

+0

Hai visto questa domanda simile? http: // StackOverflow.it/questions/14578355/system-invalidprogramexception-when-executing-unit-tests-in-mstest-after-microso – BlakeH

+0

Perché non hai ancora installato Visual Studio Update 1? – CSharpie

risposta

2

L'unica soluzione generale è assicurarsi che tutte le parti corrispondano alla versione di CLR che si sta utilizzando molto da vicino e che VS abbia gli ultimi aggiornamenti.

Non esiste un punto magico per questo problema. È necessario conoscere (scavare) l'esatta compatibilità della versione CLR di tutte le parti collegate al progetto quando si iniettano falsi. Tenete presente che la "compatibilità" potrebbe essere solo questione di manifest, ma più frequentemente sono la questione delle sfumature di come è stato generato il codice finale e per quale versione della macchina virtuale.

Queste cose normalmente non sono importanti per l'esecuzione e il debug poiché ci sono diversi livelli che assicurano che le differenze minori di versione non siano importanti o che si ottenga un passaggio silenzioso a qualsiasi cosa il proprio codice sia dichiarato compatibile.

Tuttavia, quando si utilizza Fakes, il "sistema" inietta codice non elaborato (che include le librerie di terze parti coinvolte) e significa che salta la maggior parte dei controlli - non potrebbe funzionare diversamente. Ma, quando arriva il momento di eseguire effettivamente il codice, il motore (macchina virtuale) deve fare alcuni controlli per la sua sicurezza/integrità e tende a diventare paranoico e salvare se sembra che le dichiarazioni non corrispondano abbastanza da vicino.

Questo è il motivo per cui qualcuno ha chiesto se gli assembly coinvolti sono con il nome sicuro o firmato. Questo è l'unico livello di garanzia che il "sistema" avrà davvero fiducia. Senza quello, farà un certo grado di indovinare e mentre per lo più non importa per le esecuzioni normali se conta molto per l'iniezione di codice.

Non sto ancora parlando di possibili problemi reali - tutto ciò presuppone che il codice vero sia corretto e che le dichiarazioni siano confuse. Potresti provare a giocare con questo, ma ci vorrebbe un sacco di tempo e impegno. È molto più facile controllare se è possibile ottenere versioni di assiemi che corrispondono meglio.

Il fatto che gli errori siano scomparsi quando hai cambiato il tuo sapore a 4.5 ti dice che o alcuni degli assemblaggi coinvolti non sono "abbastanza vicini" per 4.6 o ci possono essere alcuni problemi con l'iniezione di codice che sono stati corretti dagli aggiornamenti che hai ancora preso.

Sì, comporta molto dolore, ma questo è il prezzo del voler essere alla frontiera.

Problemi correlati