2010-09-24 11 views
7

estoy usando NHibernate para persistir esta entidad:¿Cómo puedo probar la unidad de propiedades protegidas que solo debe configurar NHibernate?

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

Nota cómo la propiedad Id tiene un colocador protegida. Esto es para evitar que los usuarios cambien el Id al tiempo que permiten a NHibernate asignarle un Id cuando lo guarda en la base de datos.

En una de mis pruebas de unidad, estoy usando Moq con el siguiente código para burlarse de mi repositorio:

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); 

Cuando le digo Moq devolver una nueva instancia Store, no puedo asignar el ID, y la prueba de la unidad falla. ¿Cómo pruebo esta propiedad? No quiero cambiar el nivel de acceso de la propiedad porque no quiero que los usuarios la cambien manualmente, pero eso es exactamente lo que tengo que hacer aquí para probarlo.

Respuesta

8

Si usted no está realmente a probar la clase tienda, y luego burlarse de él, y utilizar el método 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

Gracias, nunca se considera burlarse del objeto de la tienda en sí! –

+1

De nada, normalmente lo uso con interfaces, pero como ya tienes que tener todo virtual para NHibernate, este es un gran ajuste. – arootbeer

3

En el proyecto de prueba, cree una clase secundaria de Store que permita la personalización de las propiedades protegidas.

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

A continuación, configurar sus pruebas unitarias de usar devolver este caso cuando se necesita para construir un objeto Store.

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

su información, sólo tiene que agregar la clase de tienda que la clase base (no soy lo suficientemente potente como para editar :() – aqwert

+0

@aqwert Do! Gracias, hizo la actualización – JaredPar

+0

Brilliant! Mensaje viejo pero útil! – boolean

10

Sólo para tirar esto hacia fuera allí como otro enfoque, se puede hacer la incubadora protected internal:

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

y utilizar el atributo InternalsVisibleTo:

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

Oye, eso es genial. No lo había visto. antes de. –

1

Sin duda no es el mejor enfoque, pero también podría usar el reflejo para establecer la propiedad como se hace en las pruebas Sharp Architecture's.

Cuestiones relacionadas