Статический класс Mock File IO в С#

Я новичок в модульном тестировании, и мне нужно смоделировать статический класс File в пространстве имен System.IO. Я использую Rhinomock, как лучше всего это сделать,

Допустим, мне нужно издеваться над File.Exists, File.Delete...


person David MZ    schedule 27.06.2011    source источник
comment
На этом сайте уже много примеров, воспользуйтесь кнопкой поиска   -  person ChrisBint    schedule 28.06.2011
comment
возможный дубликат Mocking Static методы с использованием Rhino.Mocks   -  person sarnold    schedule 28.06.2011
comment
Иногда люди не знают, что искать, возможно, вы могли бы привести несколько примеров, а не быть совершенно бесполезными. Просто мысль.   -  person CrazyDart    schedule 28.06.2011


Ответы (7)


Вы не можете имитировать статические методы с помощью Rhino mock. См. этот вопрос для получения дополнительной информации. Вы можете создать класс фасада для переноса вызовов файловой системы, которые вы будете использовать, а затем создать его фиктивную версию.

person Don Kirkby    schedule 27.06.2011
comment
Вместо того, чтобы создавать свой собственный фасад, используйте тот, который уже написан кем-то другим: systemioabstractions.codeplex.com - person vcsjones; 28.06.2011
comment
Спасибо, это здорово, я собираюсь использовать этот с открытым исходным кодом - person David MZ; 28.06.2011
comment
Не уверен, что стал бы класть яйца в корзину, которую готовы использовать всего около 50 человек... но это ваш проект. - person CrazyDart; 28.06.2011
comment
@CrazyDart - На самом деле это не все твои яйца в корзине. Это открытый исходный код, сохраните копию исходного кода для себя, если он вам нравится. - person vcsjones; 08.07.2011

Вы должны создать службу-оболочку с именем 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");
    }
}
person CrazyDart    schedule 27.06.2011

См. также Вадима, 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();
}  
person Yann Trevin    schedule 28.06.2011

Я также использовал классы-оболочки. Я использую этот инструмент, чтобы легко создавать классы-оболочки, такие как System.IO.File.

https://www.nuget.org/packages/Digitrish.WrapperGenerator/

После того, как вы установили пакет, просто введите следующее в консоли диспетчера пакетов.

Оболочка Scaffold System.IO.File

Это создаст интерфейс IFile.cs и один конкретный класс-оболочку File.cs. Затем вы можете использовать IFile для Mock и File.cs для реальной реализации.

person Francis    schedule 27.08.2013

Почему бы не использовать MS Fakes? Разве это не было бы просто, если бы оно уже поддерживалось по сравнению с RhinoMocks, SystemWrapper.Wrapper и SystemWrapper.Interface?

person pixel    schedule 19.05.2017
comment
Насколько я понимаю, MS Fakes — это функция только для VS Enterprise. - person Shafiq Jetha; 21.12.2017
comment
Обратите внимание, что MS Fakes доступен с VS 2012 года, он разместил вопрос до этого! Раньше были родинки рассеянного склероза, но я не уверен в их пределах. - person Bahadır İsmail Aydın; 25.01.2018

В дополнение к тому, что вы не можете издеваться над Static, легко ответьте.

Я хотел бы отметить, что вы не должны издеваться над типом File.IO, потому что это не тот тип, которым вы владеете. Вы должны использовать только типы Mock, которыми владеете.

person Gishu    schedule 28.06.2011

Для этого вы можете использовать структуру moq. Это проект Google с открытым исходным кодом, который вы можете скачать здесь. Загрузить платформу Moq

Чтобы полностью понять, как использовать moq с C#, обратитесь к следующей статье.

http://learningcsharpe.blogspot.com/2011/11/how-to-use-moq-library-for-your-unit.html

спасибо, Эрандика.

person Erandika Sandaruwan    schedule 05.11.2011
comment
Moq не может тестировать статические классы, см. stackoverflow.com/questions/12580015/ - person guillem; 10.04.2013