Je suis nouveau sur Moq et je viens juste de commencer un projet déjà en développement. Je suis responsable de la mise en place des tests unitaires. Il y a une classe personnalisée pour la DatabaseFactory qui utilise EnterpriseLibrary et ressemble à ceci:MSTest avec Moq - configuration DAL
public Database CreateCommonDatabase()
{
return CreateDatabaseInstance(string.Empty);
}
private static Database CreateDatabaseInstance(string foo)
{
var database = clientCode == string.Empty
? DatabaseFactory.CreateDatabase("COMMON")
: new OracleDatabase(new ClientConnections().GetConnectionString(foo)));
return database;
}
Maintenant, voici où cela s'accoutume (resultdata est une autre classe de DataSet type):
public ResultData GetNotifications(string foo, string foo2, Database database)
{
var errMsg = string.Empty;
var retval = 0;
var ds = new DataSet();
var sqlClause =
@"[Some SELECT statement here that uses foo]";
DbCommand cm = database.GetSqlStringCommand(sqlClause);
cm.CommandType = CommandType.Text;
// Add Parameters
if (userSeq != string.Empty)
{
database.AddInParameter(cm, ":foo2", DbType.String, foo2);
}
try
{
ds = database.ExecuteDataSet(cm);
}
catch (Exception ex)
{
retval = -99;
errMsg = ex.Message;
}
return new ResultData(ds, retval, errMsg);
}
Maintenant, à l'origine , la base de données n'a pas été transmise en tant que paramètre, mais la méthode créait une nouvelle instance de DatabaseFactory à l'aide de la méthode CreateCommonDatabase et l'utilisait à partir de là. Cependant, cela rend la classe impossible à tester car je ne peux pas l'empêcher de toucher la base de données. Donc, je suis allé avec Dependency Injection, et passer la base de données.
Maintenant, je suis coincé, car il n'y a aucun moyen de se moquer de la base de données afin de tester GetNotifications. Je me demande si je complique trop les choses ou s'il me manque quelque chose. Est-ce que je fais cela de la bonne façon, ou devrais-je repenser comment j'ai mis en place cette configuration?
Modifier pour ajouter plus d'informations *****
Je ne veux vraiment pas tester la base de données. Je veux que la classe Data.Notifications (ci-dessus) retourne une instance de ResultData, mais c'est tout ce que je veux vraiment tester. Si je vais un haut niveau, à la couche d'affaires, j'ai ceci:
public DataSet GetNotifications(string foo, string foo1, out int returnValue, out string errorMessage, Database database)
{
ResultData rd = new data.Notifications().GetNotifications(foo, foo1, database);
returnValue = rd.ResultValue;
errorMessage = rd.ErrorMessage;
return rd.DataReturned;
}
Ainsi, à l'origine, la base de données n'a pas été transmis, ce fut la classe Data.Notifications qui l'a créé - mais là encore, Si je l'ai laissé comme ça, je n'ai pas pu m'empêcher de cliquer sur la base de données pour tester cet objet de couche Business. J'ai modifié tout le code pour passer la base de données (qui est créée sur la page de base du site web), mais maintenant je ne suis pas sûr de ce que je vais faire. Je pensais que j'étais un test unitaire loin d'avoir résolu cela, mais apparemment, soit je me trompe ou j'ai un barrage mental sur le bon chemin.
En plus de mon code de test, je voudrais aussi vous recommander de vous éloigner des DataSets, s'il n'est pas trop tard. Les jeux de données particulièrement non typés ont tendance à produire un code plus fragile, selon mon expérience. Bonne chance. –
Anderson - Je suis totalement d'accord, mais ce n'est pas mon choix, malheureusement. Je vais devoir parler bientôt à l'architecte de la mise en œuvre de l'inversion de contrôle/de l'injection de dépendances, mais je pense que ces changements sont à peu près aussi loin que je pourrais le faire. –
bien au moins vous serez la voix de quelque raison. Je travaillerais pour que votre code soit aussi proche que possible de l'injection de dépendance, de sorte que lorsque vous serez capable d'utiliser un outil comme Unity (ou un autre conteneur IoC), vous serez prêt à retourner un commutateur. –