Une des limites des api de mocking (moq ou rhino mocks par exemple) est l’absence de fonctionnalité permettant de mocker des propriétés/méthodes statiques (du framework .net ou pas). De ce fait, comment faire pour tester la méthode “DoSomething” suivante :
public class MyClass
{
public string DoSomething()
{
if (File.Exists("filePath"))
{
return "OK";
}
else
{
return "KO";
}
}
}
Pour pouvoir tester cette méthode, on pourrait créer un service qui encapsulerait l’appel la méthode System. IO. File. Exists :
public class FileService : IFileService
{
public bool FileExits(string path)
{
return File.Exists(path);
}
}
Et on modifierait notre méthode de façon à utiliser notre service dans le but de le mocker dans nos tests :
public class MyClass
{
private IFileService _fs;
public MyClass(IFileService fs)
{
_fs = fs;
}
public string DoSomething()
{
if (_fs.FileExits("filePath"))
{
return "OK";
}
return "KO";
}
}
Un peu lourd non ? Pas de soucis, Le framework Microsoft Fakes va nous permettre d’éviter cette lourdeur avec un « Shim”. Présent sur les versions Premium et Ultimate de visual studio 2012 le « Shim” va modifié le code compilé au runtime et appellera dans notre cas, non plus la méthode FileExits, mais la méthode que nous allons lui définir.
Pour utiliser ces Shim, il faut dans un premier temps ajouter la fake assembly qui nous intéresse. File étant dans l’assembly System, on fait un clic droit sur la référence System et on clique sur « Add Fakes Assembly”:
Il nous reste plus ensuite qu’à rédiger nos tests unitaires de la manière suivante :
[TestMethod]
public void DoSomething_ReturnOK()
{
using (ShimsContext.Create())
{
//ARRANGE
System.IO.Fakes.ShimFile.ExistsString = (path) => { return true; };
//ACT
MyClass m = new MyClass();
string result = m.DoSomething();
//ASSERT
Assert.AreEqual("OK", result);
}
}
[TestMethod]
public void DoSomething_ReturnKO()
{
using (ShimsContext.Create())
{
//ARRANGE
System.IO.Fakes.ShimFile.ExistsString = (path) => { return false; };
//ACT
MyClass m = new MyClass();
string result = m.DoSomething();
//ASSERT
Assert.AreEqual("KO", result);
}
}
Evidemment, on peut aussi créer des Shim sur nos propres assemblies.