Inti dari perpustakaan adalah IFileSystem
dan FileSystem
. Alih -alih memanggil metode seperti File.ReadAllText
secara langsung, gunakan IFileSystem.File.ReadAllText
. Kami memiliki API yang sama persis, kecuali bahwa kami disuntikkan dan dapat diuji.
dotnet add package TestableIO.System.IO.Abstractions.Wrappers
Catatan: Paket Nuget ini juga diterbitkan sebagai System.IO.Abstractions
tetapi kami menyarankan untuk menggunakan awalan untuk memperjelas bahwa ini bukan paket .NET resmi.
public class MyComponent
{
readonly IFileSystem fileSystem ;
// <summary>Create MyComponent with the given fileSystem implementation</summary>
public MyComponent ( IFileSystem fileSystem )
{
this . fileSystem = fileSystem ;
}
/// <summary>Create MyComponent</summary>
public MyComponent ( ) : this (
fileSystem : new FileSystem ( ) //use default implementation which calls System.IO
)
{
}
public void Validate ( )
{
foreach ( var textFile in fileSystem . Directory . GetFiles ( @"c:" , " *.txt " , SearchOption . TopDirectoryOnly ) )
{
var text = fileSystem . File . ReadAllText ( textFile ) ;
if ( text != " Testing is awesome. " )
throw new NotSupportedException ( " We can't go on together. It's not me, it's you. " ) ;
}
}
}
Perpustakaan juga mengirimkan serangkaian pembantu uji untuk menyelamatkan Anda dari keharusan mengejek setiap panggilan, untuk skenario dasar. Mereka bukan salinan lengkap dari sistem file kehidupan nyata, tetapi mereka akan membawa Anda sebagian besar jalan ke sana.
dotnet add package TestableIO.System.IO.Abstractions.TestingHelpers
Catatan: Paket Nuget ini juga diterbitkan sebagai System.IO.Abstractions.TestingHelpers
tetapi kami sarankan untuk menggunakan awalan untuk memperjelas bahwa ini bukan paket .NET resmi.
[ Test ]
public void MyComponent_Validate_ShouldThrowNotSupportedExceptionIfTestingIsNotAwesome ( )
{
// Arrange
var fileSystem = new MockFileSystem ( new Dictionary < string , MockFileData >
{
{ @"c:myfile.txt" , new MockFileData ( " Testing is meh. " ) } ,
{ @"c:demojQuery.js" , new MockFileData ( " some js " ) } ,
{ @"c:demoimage.gif" , new MockFileData ( new byte [ ] { 0x12 , 0x34 , 0x56 , 0xd2 } ) }
} ) ;
var component = new MyComponent ( fileSystem ) ;
try
{
// Act
component . Validate ( ) ;
}
catch ( NotSupportedException ex )
{
// Assert
Assert . That ( ex . Message , Is . EqualTo ( " We can't go on together. It's not me, it's you. " ) ) ;
return ;
}
Assert . Fail ( " The expected exception was not thrown. " ) ;
}
Kami bahkan mendukung casting dari tipe .NET Framework yang tidak dapat diestestasikan ke pembungkus kami yang dapat diuji:
FileInfo SomeApiMethodThatReturnsFileInfo ( )
{
return new FileInfo ( " a " ) ;
}
void MyFancyMethod ( )
{
var testableFileInfo = ( FileInfoBase ) SomeApiMethodThatReturnsFileInfo ( ) ;
.. .
}
Karena versi 4.0 API tingkat atas mengekspos antarmuka alih-alih kelas dasar abstrak (meskipun ini masih ada), memungkinkan Anda untuk benar-benar mengejek sistem file. Inilah contoh kecil, menggunakan MOQ:
[ Test ]
public void Test1 ( )
{
var watcher = Mock . Of < IFileSystemWatcher > ( ) ;
var file = Mock . Of < IFile > ( ) ;
Mock . Get ( file ) . Setup ( f => f . Exists ( It . IsAny < string > ( ) ) ) . Returns ( true ) ;
Mock . Get ( file ) . Setup ( f => f . ReadAllText ( It . IsAny < string > ( ) ) ) . Throws < OutOfMemoryException > ( ) ;
var unitUnderTest = new SomeClassUsingFileSystemWatcher ( watcher , file ) ;
Assert . Throws < OutOfMemoryException > ( ( ) => {
Mock . Get ( watcher ) . Raise ( w => w . Created += null , new System . IO . FileSystemEventArgs ( System . IO . WatcherChangeTypes . Created , @"C:SomeDirectory" , " Some.File " ) ) ;
} ) ;
Mock . Get ( file ) . Verify ( f => f . Exists ( It . IsAny < string > ( ) ) , Times . Once ) ;
Assert . True ( unitUnderTest . FileWasCreated ) ;
}
public class SomeClassUsingFileSystemWatcher
{
private readonly IFileSystemWatcher _watcher ;
private readonly IFile _file ;
public bool FileWasCreated { get ; private set ; }
public SomeClassUsingFileSystemWatcher ( IFileSystemWatcher watcher , IFile file )
{
this . _file = file ;
this . _watcher = watcher ;
this . _watcher . Created += Watcher_Created ;
}
private void Watcher_Created ( object sender , System . IO . FileSystemEventArgs e )
{
FileWasCreated = true ;
if ( _file . Exists ( e . FullPath ) )
{
var text = _file . ReadAllText ( e . FullPath ) ;
}
}
}
System.IO.Abstractions.Extensions
menyediakan fungsionalitas kenyamanan di atas abstraksi inti.
System.IO.Abstractions.Analyzers
menyediakan penganalisa Roslyn untuk membantu menggunakan abstraksi atas metode statis.
Testably.Abstractions
memberikan pembantu uji alternatif dan abstraksi tambahan.