Я новичок в модульном тестировании, и мне нужно смоделировать статический класс File в пространстве имен System.IO. Я использую Rhinomock, как лучше всего это сделать,
Допустим, мне нужно издеваться над File.Exists, File.Delete...
Я новичок в модульном тестировании, и мне нужно смоделировать статический класс File в пространстве имен System.IO. Я использую Rhinomock, как лучше всего это сделать,
Допустим, мне нужно издеваться над File.Exists, File.Delete...
Вы не можете имитировать статические методы с помощью Rhino mock. См. этот вопрос для получения дополнительной информации. Вы можете создать класс фасада для переноса вызовов файловой системы, которые вы будете использовать, а затем создать его фиктивную версию.
Вы должны создать службу-оболочку с именем IFileService, затем вы можете создать конкретный объект, который использует статику для использования в вашем приложении, и фиктивный IFileService, который будет иметь поддельную функциональность для тестирования. Сделайте так, чтобы вам приходилось передавать IFileService в конструктор или свойство для любого класса, который его использует, таким образом, нормальная работа требует, чтобы вы передавали IFileService. Помните, что при модульном тестировании вы тестируете только ту часть кода, а не то, к чему он обращается, например IFileService.
interface IFileService
{
bool Exists(string fileName);
void Delete(string fileName);
}
class FileService : IFileService
{
public bool Exists(string fileName)
{
return File.Exists(fileName);
}
public void Delete(string fileName)
{
File.Delete(fileName);
}
}
class MyRealCode
{
private IFileService _fileService;
public MyRealCode(IFileService fileService)
{
_fileService = fileService;
}
void DoStuff()
{
_fileService.Exists("myfile.txt");
}
}
См. также Вадима, SystemWrapper. Вы можете смоделировать множество системных классов, но вам понадобится чтобы применить шаблон внедрения зависимостей, чтобы сделать код пригодным для тестирования.
[Test]
public void Check_that_FileInfo_methods_Create_and_Delete_are_called()
{
// Add mock repository.
IFileInfoWrap fileInfoRepository = MockRepository.GenerateMock<IFileInfoWrap>();
IFileStreamWrap fileStreamRepository = MockRepository.GenerateMock<IFileStreamWrap>();
// Create expectations
fileInfoRepository.Expect(x => x.Create()).Return(fileStreamRepository);
fileStreamRepository.Expect(x => x.Close());
fileInfoRepository.Expect(x => x.Delete());
// Test
new FileInfoSample().CreateAndDeleteFile(fileInfoRepository);
// Verify expectations.
fileInfoRepository.VerifyAllExpectations();
fileStreamRepository.VerifyAllExpectations();
}
Я также использовал классы-оболочки. Я использую этот инструмент, чтобы легко создавать классы-оболочки, такие как System.IO.File.
https://www.nuget.org/packages/Digitrish.WrapperGenerator/
После того, как вы установили пакет, просто введите следующее в консоли диспетчера пакетов.
Оболочка Scaffold System.IO.File
Это создаст интерфейс IFile.cs и один конкретный класс-оболочку File.cs. Затем вы можете использовать IFile для Mock и File.cs для реальной реализации.
Почему бы не использовать MS Fakes? Разве это не было бы просто, если бы оно уже поддерживалось по сравнению с RhinoMocks, SystemWrapper.Wrapper и SystemWrapper.Interface?
В дополнение к тому, что вы не можете издеваться над Static, легко ответьте.
Я хотел бы отметить, что вы не должны издеваться над типом File.IO, потому что это не тот тип, которым вы владеете. Вы должны использовать только типы Mock, которыми владеете.
Для этого вы можете использовать структуру moq. Это проект Google с открытым исходным кодом, который вы можете скачать здесь. Загрузить платформу Moq
Чтобы полностью понять, как использовать moq с C#, обратитесь к следующей статье.
http://learningcsharpe.blogspot.com/2011/11/how-to-use-moq-library-for-your-unit.html
спасибо, Эрандика.