2010-10-08 5 views
0

J'ai essayé de tester une unité dans la couche base de données de mon application. Dans mon test j'avais l'intention d'écrire des simulacres pour éviter d'avoir une connexion en direct à MySQL. Je vais écrire une version simplifiée de mon code pour illustrer. Commençons par le test unitaire:Méthode C# unitesting avec la requête MySql

[TestMethod()] 
public void TestMethod1() 
{ 

DataBaseInterface database = new DataBaseInterface(); // this is the class which has the method I want to unit test 

DataSet ds = new DataSet(); 

ds.Tables.Add(new DataTable("signals")); 

ds.Tables[0].Columns.Add(new DataColumn("ID")); 
ds.Tables[0].Columns.Add(new DataColumn("Content")); 

DataRow row = ds.Tables[0].NewRow(); 

row["ID"] = "1"; 
row["Content"] = "Foo"; 

ds.Tables[0].Rows.Add(row); 

MockDataBaseConnection db = new MockDataBaseConnection(); 


string result = database.GetContent(1); // this is the method I want to unit test 

} 

La méthode que je veux tester l'unité ressemble à ceci:

public class DatabaseInterface 
{ 

private MySqlConnectionAdapter _sqlConn; 

public string GetContent(int i) 
{ 

MySqlCommand command = _sqlConn.CreateCommand(); 

command.CommandText = String.Format(""); 

_sqlConn.Open(); 

MySqlDataReader reader = command.ExecuteReader(); 

/// more code here 


} 

Pour éviter d'utiliser une connexion de base de données réelle dans mon UNITEST j'ai écrit quelques mockups et ici se trouve le problème. Les mockups ressemble à ceci:

public class MySqlConnectionAdapter 
    { 
     public MySqlConnection _sqlConn; 

     public MySqlConnectionAdapter() 
     { 
     } 

     public MySqlConnectionAdapter(string con) 
     { 
      _sqlConn = new MySqlConnection(con); 
     } 

     public event MySqlInfoMessageEventHandler InfoMessage 
     { 
      add 
      { 
       _sqlConn.InfoMessage += value; 
      } 
      remove 
      { 
       _sqlConn.InfoMessage -= value; 
      } 
     } 

     public virtual event StateChangeEventHandler StateChange 
     { 
      add 
      { 
       _sqlConn.StateChange += value; 
      } 
      remove 
      { 
       _sqlConn.StateChange -= value; 
      } 
     } 

     public virtual void Open() 
     { 
      _sqlConn.Open(); 
     } 

     public void Close() 
     { 
      _sqlConn.Close(); 
     } 

     public string ServerVersion 
     { 
      get 
      { 
       return _sqlConn.ServerVersion; 
      } 
     } 

     protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) 
     { 
      return _sqlConn.BeginTransaction(isolationLevel); 
     } 

     public void ChangeDatabase(string databaseName) 
     { 
      _sqlConn.ChangeDatabase(databaseName); 
     } 


     public string ConnectionString 
     { 
      get 
      { 
       return _sqlConn.ConnectionString; 
      } 
      set 
      { 
       _sqlConn.ConnectionString = value; 
      } 
     } 

     public virtual MySqlCommand CreateCommand() 
     { 
      return _sqlConn.CreateCommand(); 
     } 

     public string DataSource 
     { 
      get 
      { 
       return _sqlConn.DataSource; 
      } 
     } 

     public string Database 
     { 
      get 
      { 
       return _sqlConn.Database; 
      } 
     } 

     public ConnectionState State 
     { 
      get 
      { 
       return _sqlConn.State; 
      } 
     } 
    } 

public class MockDataBaseConnection : MySqlConnectionAdapter 
    { 
     public DataSet ds; 

     public new MockMySqlCommand CreateCommand() 
     { 
      return new MockMySqlCommand(ds); 
     } 
    } 

    public class MockMySqlCommand 
    { 
     private DataSet _ds; 

     public MockMySqlReader ExcecuteReader() 
     { 
      return new MockMySqlReader(_ds); 
     } 

     public MockMySqlCommand(DataSet ds) 
     { 
      _ds = ds; 
     } 
    } 

    public class MockMySqlReader 
    { 
     public DataSet _ds; 

     private int currRow = 0; 

     public MockMySqlReader(DataSet ds) 
     { 
      _ds = ds; 
     } 

     public bool Read() 
     { 
      if (currRow < _ds.Tables[0].Rows.Count) 
      { 
       currRow++; 
       return true; 
      } 
      else return false; 
     } 

     public object GetValue(int i) 
     { 
      return _ds.Tables[0].Rows[currRow][i]; 
     } 
    } 

Lorsque la ligne _sqlConn.CreateCommand() est exécuté, il lance et exeption. Pourquoi donc? Les éléments _sqlConn dans ma méthode de test unitaire sont un objet MockDataBaseConnection et je souhaite qu'il retourne un objet MockMySqlCommand.

Le scellé classé de la DLL MySQL me donne mal à la tête. Quelqu'un peut-il expliquer comment je peux réparer mon code ou montrer un exemple simple de la façon de tester unitairement une méthode qui interroge une base de données sans réellement interroger la base de données.

+0

serait-il pas beaucoup plus facile interroger un local, tester, base de données? – vulkanino

+0

yup, je suppose. Je n'ai pas encore terminé ce bit. Je n'ai pas pu trouver de solution, donc je teste en utilisant la même base de données (ou similaire) que celle que je prévois d'utiliser en production. – Filip

Répondre

0

Comme suggéré par vulkanino, je pense qu'il serait beaucoup plus facile de configurer une instance de base de données locale, et d'exécuter les tests directement dessus.

Je suis dans la même situation, et a développé ce projet qui définit simplement une marche locale MySql instance de serveur de test, sans avoir à vous soucier de l'administration du serveur: https://github.com/stumpdk/MySql.Server