Это дополнительный вопрос к Модульное тестирование с зависимостями ввода / вывода .
Как мне заставить PngBitmapEncoder принять упакованный / поддельный FileStream?
В BitmapService.SaveBitmapAsPngImage () я хочу утверждать, что битовый кодировщик вызывает потоковое сохранение
bitmapEncoder.Save (outStream.StreamInstance);
Пробный тест Rhino, для которого требуется "действительный" FileStream для PngBitmapEncoder:
[Test]
public void BitmapService_Should_SaveBitmapAsPngImage_RhinoMocks()
{
// Arrange
IFile fileMock = MockRepository.GenerateStrictMock<IFile>();
IFileStream fileStreamWrapperMock = MockRepository.GenerateStub<IFileStream>();
fileMock.Expect(x => x.Open(string.Empty, FileMode.OpenOrCreate))
.IgnoreArguments().Return(fileStreamWrapperMock);
var bitmapEncoderFactory = MockRepository.GenerateStub<IBitmapEncoderFactory>();
PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
bitmapEncoderFactory.Expect(x => x.CreateBitmapEncoder()).Return(pngBitmapEncoder);
BitmapService sut = new BitmapService(fileMock, new PngBitmapEncoderFactory());
Size renderSize = new Size(100, 50);
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(
(int)renderSize.Width, (int)renderSize.Height, 96d, 96d, PixelFormats.Pbgra32);
// Act
sut.SaveBitmapAsPngImage(new Uri("//A_valid_path"), renderBitmap);
// Assert
pngBitmapEncoder.AssertWasCalled(x => x.Save(fileStreamWrapperMock.FileStreamInstance));
}
Результат теста Rhino:
System.ArgumentNullException: значение не может быть нулевым.
Имя параметра: поток
в System.Windows.Media.StreamAsIStream.IStreamFrom (потоковый поток)
в System.Windows.Media.Imaging.BitmapEncoder.Save (Поток)
at BitmapService.SaveBitmapAsPngImage (путь Uri, BitmapSource renderBitmap)
Я предпочитаю макеты Rhino, но вот тест Moq от @ Nkosi . К сожалению, это тоже не работает:
[TestMethod]
public void BitmapService_Should_SaveBitmapAsPngImage()
{
//Arrange
var mockedStream = Mock.Of<Stream>(_ => _.CanRead == true && _.CanWrite == true);
Mock.Get(mockedStream).SetupAllProperties();
var fileSystemMock = new Mock<IFileSystem>();
fileSystemMock
.Setup(_ => _.OpenOrCreateFileStream(It.IsAny<string>()))
.Returns(mockedStream);
var sut = new BitmapService(fileSystemMock.Object);
Size renderSize = new Size(100, 50);
var renderBitmap = new RenderTargetBitmap(
(int)renderSize.Width, (int)renderSize.Height, 96d, 96d, PixelFormats.Pbgra32);
var path = new Uri("//A_valid_path");
//Act
sut.SaveBitmapAsPngImage(path, renderBitmap);
//Assert
Mock.Get(mockedStream)
.Verify(_ => _.Write(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()));
}
Результат теста Moq:
BitmapServiceTest.BitmapService_Should_SaveBitmapAsPngImage threw
исключение: System.IO.IOException: невозможно прочитать из потока. --->
System.Runtime.InteropServices.COMException: исключение из HRESULT:
0x88982F72
at System.Windows.Media.Imaging.BitmapEncoder.Save (Поток)
Итак, тест пытается использовать этот поток.
Тестируемый класс:
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SystemInterface.IO;
using SystemWrapper.IO;
public interface IBitmapService
{
void SaveBitmapAsPngImage(Uri path, BitmapSource renderBitmap);
}
public interface IBitmapEncoderFactory
{
BitmapEncoder CreateBitmapEncoder();
}
public class PngBitmapEncoderFactory : IBitmapEncoderFactory
{
public BitmapEncoder CreateBitmapEncoder()
{
return new PngBitmapEncoder();
}
}
public class BitmapService : IBitmapService
{
private readonly IFile _fileWrapper;
private readonly IBitmapEncoderFactory _bitmapEncoderFactory;
public BitmapService(IFile fileWrapper, IBitmapEncoderFactory bitmapEncoderFactory)
{
_fileWrapper = fileWrapper;
_bitmapEncoderFactory = bitmapEncoderFactory;
}
public void SaveBitmapAsPngImage(Uri path, BitmapSource renderBitmap)
{
// Create a file stream for saving image
using (IStream outStream = _fileWrapper
.Open(path.LocalPath, FileMode.OpenOrCreate))
{
// Use bitmap encoder for our data
BitmapEncoder bitmapEncoder = _bitmapEncoderFactory.CreateBitmapEncoder();
// push the rendered bitmap to it
bitmapEncoder.Frames.Add(BitmapFrame.Create(renderBitmap));
// The problem: Expects real Stream as parameter!!!
bitmapEncoder.Save(outStream.StreamInstance);
}
}
}