2009-11-06 3 views
16

Ho una classe chiamata "Sessione" che espone diversi metodi pubblici. Mi piacerebbe Unit Test, tuttavia in produzione ho bisogno di controllare l'istanza degli oggetti "Session", quindi delegare la costruzione a una classe SessionManager e rendere interno il costruttore della Session.Unità Test di una classe con un costruttore interno

Preferirei testare la classe Session in isolamento da SessionManager che lo crea per dimostrare che le interfacce pubbliche esposte dalla Session funzionano come previsto, ma non è possibile creare un'istanza di una sessione da un test senza utilizzare un SessionManager che rende i miei test più complicati/meno utili di quanto debbano essere.

Qual è il modo migliore per affrontare questo?

Cheers,

Lenny.

+0

Plese chiarire: è è protetto ___or_ un costruttore interno? –

risposta

42

Nulla vi impedisce di interni di test Basta fare l'interno del codice visibile per la suite di test, utilizzando l'attributo InternalsVisibleTo:.. in AssemblyInfo, aggiungere

[assembly:InternalsVisibleTo("TestSuiteAssembly")] 
+0

Questo sembra essere il modo più semplice per farlo, quindi penso che correrò con questo. Grazie. –

+1

La risposta non è davvero completa - gli assembly devono essere firmati per farlo funzionare. – Santhos

+0

@Santhos non proprio ... –

2

Si potrebbe semplicemente rendere la classe di test dell'unità ereditata da Session (presupponendo che il framework di test non richieda di ereditare da una classe specifica). Ad esempio, con NUnit:

[TestFixture] 
public class SessionTest : Session 
{ 
    public SessionTest() 
     : base() // call protected constructor 
    { 
    } 

    [Test] 
    public void TestSomething() 
    { 
    } 

} 
+1

OP detto ctor è interno, non protetto. –

+0

@Rex - il titolo della domanda dice protetto, mentre la domanda stessa dice interna. –

1

Si desidera utilizzare un prodotto come TypeMock, che vi permetterà di creare deriso (finto) istanze di classi, come questo:

var myInstance = Isolate.Fake.Instance<Session>(); 
// mock behavior here 
// do assertions here 

È possibile creare istanze di classi astratte con TypeMock, per la cronaca.

+3

il mocking della stessa classe che vuoi testare non ha molto senso per me però ... non dovresti testare la simulazione e non la classe allora? – Svish

+0

@Svish, hai ragione che il comportamento simulato non è utile, ma può anche creare un'istanza reale e risolvere il problema dell'accessibilità: Isolate.Fake.Instance (Members.CallOriginal). In questo modo hai un'istanza reale della classe con chi è costruttore non accessibile. Disclaimer - Lavoro a Typemock. – Elisha

2

In alternativa, come soluzione alternativa, è sufficiente creare una TestSession che eredita da Session ed espone un costruttore pubblico. All'interno del test dell'unità, quindi, si utilizza TestSession che fondamentalmente fa la stessa cosa dell'oggetto Session originale.

public class TestSession : Session 
{ 

    public TestSession() : base() 
    { 

    } 

} 
1

Vorrei mettere in discussione il valore di rendere interno il costruttore della classe di sessione.

Generalmente ciò implica che si sta tentando di impedire ad altri sviluppatori di utilizzare la classe. Forse sarebbe meglio comunicare come funziona questa particolare parte dell'applicazione e perché vorresti solo accedere alla sessione dal gestore della sessione?

+0

L'ho visto fare molto con un modello factory, in cui si potrebbe voler far rispettare che la classe è sempre creata o distrutta in un unico posto, ma ad altre persone è consentito fare riferimento e usarlo. –

+0

L'ho visto molto anche io :) Solo che non vedo come aggiunge valore. Causa solo problemi quando si desidera estendere o testare, proprio come Leonard sta vivendo ora. MS è uno dei peggiori trasgressori in questo senso, ci sono un sacco di classi interne che sarebbe utile usare a volte, ma non possiamo accedervi! Frustraing! –

+5

Come qualcuno che era un consumatore di API ed era molto frustrato come se ti chiedessi perché MS rende così tante cose interne, protette, ecc. Ora faccio principalmente lo sviluppo dell'API e il mio materiale viene consumato da altri sviluppatori. Trascorro molto tempo a ripulire i pasticci degli altri perché si mettono nei guai usando roba che dovrei aver fatto all'interno. A volte non è realistico aspettarsi di essere in grado di comunicare l'uso "corretto" di ogni pezzo di codice che scriviamo. –

0

Se è possibile uscire con un costruttore "protetto interno", supponendo che i test siano in un gruppo diverso, è possibile aggiungere l'attributo InternalsVisibleTo al "assembly da testare". Ciò consentirebbe i test di vedere i membri interni del to-be-testato-assemblaggio".

Aggiornamento Per qualche ragione ho letto che il costruttore è stato protetto. E 'già interno in modo che siano in una buona posizione per utilizzare l'attributo