asp.net-mvc unit-testing moq httppostedfilebase

asp.net mvc - Simulación de HttpPostedFileBase y InputStream para prueba de unidad



asp.net-mvc unit-testing (3)

Quiero probar la siguiente línea de código:

... Bitmap uploadedPicture = Bitmap.FromStream(model.Picture.InputStream) as Bitmap; ...

La imagen es una propiedad en mi tipo de modelo HttpPostedFileBase. Así que me gustaría simular una propiedad HttpPostedFileBase para la prueba de la unidad:

model.Picture = new Mock<HttpPostedFileBase>().Object;

No hay problema.

Ahora tengo que burlarme de InputStream, de lo contrario es nulo:

model.Picture.InputStream = new Mock<Stream>().Object;

Esto no funciona, ya que InputStream es de solo lectura (no tiene un método de establecimiento):

public virtual Stream InputStream { get; }

¿Hay una manera buena y limpia de manejar este problema? Una solución sería anular HttpPostedFileBase en una clase derivada para mi prueba de unidad. ¿Alguna otra idea?


Acabo de estar trabajando en algo similar y quería agregar lo siguiente a la respuesta de @ TiagoC13.

Mi sistema bajo prueba fue un servicio de archivos que estoy escribiendo, uno de los requisitos es probar que un archivo tenga las dimensiones correctas. Tenga en cuenta, el nombre de archivo codificado. Esto existe como una carpeta y un archivo en mi proyecto de prueba. Las propiedades del archivo son las siguientes: Acción de compilación: Recurso incrustado y Copiar en el Directorio de salida: Copiar si es más reciente (aunque Copiar siempre debería funcionar bien)

Cuando se construye el proyecto, el archivo testimage.jpg y su carpeta se agregan al contenedor donde luego se encuentra la prueba.

También tenga en cuenta el fileStream.Close (); esto libera el archivo para que pueda tener una serie de pruebas similares en la misma suite.

Espero que esto sea de ayuda.

using Moq; using NUnit.Framework; using System.Web; [Test] public void IsValidFile() { string filePath = Path.GetFullPath(@"testfiles/testimage.jpg"); FileStream fileStream = new FileStream(filePath, FileMode.Open); Mock<HttpPostedFileBase> uploadedFile = new Mock<HttpPostedFileBase>(); uploadedFile .Setup(f => f.ContentLength) .Returns(10); uploadedFile .Setup(f => f.FileName) .Returns("testimage.jpg"); uploadedFile .Setup(f => f.InputStream) .Returns(fileStream); var actual = fileSystemService.IsValidImage(uploadedFile.Object, 720, 960); Assert.That(actual, Is.True); fileStream.Close(); }


Hola :) Hice algo como

[TestInitialize] public void SetUp() { _stream = new FileStream(string.Format( ConfigurationManager.AppSettings["File"], AppDomain.CurrentDomain.BaseDirectory), FileMode.Open); // Other stuff }

Y en la propia prueba,

[TestMethod] public void FileUploadTest() { // Other stuff #region Mock HttpPostedFileBase var context = new Mock<HttpContextBase>(); var request = new Mock<HttpRequestBase>(); var files = new Mock<HttpFileCollectionBase>(); var file = new Mock<HttpPostedFileBase>(); context.Setup(x => x.Request).Returns(request.Object); files.Setup(x => x.Count).Returns(1); // The required properties from my Controller side file.Setup(x => x.InputStream).Returns(_stream); file.Setup(x => x.ContentLength).Returns((int)_stream.Length); file.Setup(x => x.FileName).Returns(_stream.Name); files.Setup(x => x.Get(0).InputStream).Returns(file.Object.InputStream); request.Setup(x => x.Files).Returns(files.Object); request.Setup(x => x.Files[0]).Returns(file.Object); _controller.ControllerContext = new ControllerContext( context.Object, new RouteData(), _controller); // The rest... }

Espero que esto pueda dar una idea a su solución :)


No es necesario crear una secuencia para abrir un archivo en el disco. En realidad creo que es una solución bastante horrible. Una secuencia de prueba de trabajo se puede crear fácilmente en memoria.

var postedFile = new Mock<HttpPostedFileBase>(); using (var stream = new MemoryStream()) using (var bmp = new Bitmap(1, 1)) { var graphics = Graphics.FromImage(bmp); graphics.FillRectangle(Brushes.Black, 0, 0, 1, 1); bmp.Save(stream, ImageFormat.Jpeg); postedFile.Setup(pf => pf.InputStream).Returns(stream); // Assert something with postedFile here }