2010-09-24 15 views
7

Sto usando NHibernate a persistere questa entità:In che modo le proprietà protette da test unitari devono essere impostate solo da NHibernate?

public class Store 
{ 
    public int Id { get; protected set; } 
    public int Name { get; set; } 
} 

Nota come la proprietà Id ha un setter protetto. Questo per impedire agli utenti di modificare lo Id mentre ancora consente a NHibernate di assegnargli uno Id quando lo salva nel database.

In uno dei miei test di unità, sto usando Moq con il seguente codice di deridere il mio repository:

var mock = new Mock<IRepository>(); 
mock.Setup(x => x.GetById<Store>(It.IsAny<int>())) 
    .Returns(new Store { Value = "Walmart" }); // can't set the ID here 

var store = Repository.GetById<Store>(5); 
Assert.That(store.Id == 5); 

Quando dico Moq per restituire una nuova Store esempio, non posso assegnare il ID e il test dell'unità fallisce. Come posso testare questa proprietà? Non voglio modificare il livello di accesso della proprietà perché non voglio che gli utenti lo modifichino manualmente, eppure questo è esattamente quello che devo fare qui per testarlo.

risposta

8

Se non sta effettivamente testare la classe Store, quindi prendere in giro, e utilizzare il metodo SetupGet:

var mock = new Mock<IRepository>(); 
var mockStore = new Mock<Store>(); 
mock.Setup(x => x.GetById<Store>(It.IsAny<int>())).Returns(mockStore.Object); 

mockStore.SetupGet(s => s.Id).Returns(5); 
mockStore.SetupGet(s => s.Value).Returns("Walmart"); 

var store = Repository.GetById<Store>(5); 
Assert.That(store.Id == 5); 
+0

Grazie, non ho mai –

+1

Prego, di solito uso questo con le interfacce, ma dal momento che devi già avere tutto virtuale per NHibernate, comunque, questo è un ottimo adattamento – arootbeer

3

Nel progetto di test creare una classe figlio di Store che consente la personalizzazione delle proprietà protette.

class TestableStore : Store { 
    public int TestableId { 
    get { return Id; } 
    set { Id = value; } 
    } 
} 

Poi configurare i test di unità da utilizzare restituire questo esempio quando è necessario costruire un oggetto Store.

mock 
    .Setup(x => x.GetById<Store>(It.IsAny<int>())) 
    .Returns(new TestableStore { Value = "Walmart", TestableId=42 }); 
+0

FYI, è sufficiente aggiungere la classe Store come classe base (non sono abbastanza potente da modificare :() – aqwert

+0

@aqwert doh! Grazie, ha effettuato l'aggiornamento – JaredPar

+0

Brilliant! Vecchio post ma utile! – boolean

10

solo per gettare questo fuori là come un altro approccio, si potrebbe fare il setter protected internal:

public class Store 
{ 
    public int Id { get; protected internal set; } 
    public int Name { get; set; } 
} 

e utilizzare l'attributo InternalsVisibleTo:

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

Ehi, è davvero bello. prima. –

1

Certamente non l'approccio migliore, ma è anche possibile utilizzare la riflessione per impostare la proprietà come avviene nei test Sharp Architecture's.

Problemi correlati