2011-06-16 19 views
5

Estoy intentando simular las operaciones de la base de datos. Tengo un problema al burlarse de SqlParameterCollection. Traté de crear el método virtual que devolverá DbParameterCollection pero luego estoy perdiendo toda la funcionalidad que SqlParameterCollection da como SqlParameterCollection etc. ¿Hay alguna manera de burlarme de SqlParameterCollection? ¿Hay algún otro enfoque para probar la unidad DAL? Estoy usando Moq.Cómo simular SqlParameterCollection usando Moq

Código es la siguiente:

en DAL:

protected virtual IDbConnection GetConnection(string connectionString) 
{ 
    return new SqlConnection(connectionString); 
} 

protected virtual IDbCommand GetCommand(IDbConnection cn) 
{ 
    return cn.CreateCommand(); 
} 

protected virtual IDbTransaction GetTransaction(IDbConnection cn) 
{ 
    return cn.BeginTransaction(IsolationLevel.Serializable); 
} 

Public Bool InsertInDatabase(DataTable dt) 
{ 
    using (IDbConnection cn = GetConnection(cnstr)) 
     { 
     cn.Open(); 

      using (IDbTransaction tran = GetTransaction(cn)) 
      { 
       IDbCommand cmd = GetCommand(cn); 
       cmd.Transaction = tran; 
       cmd.Connection = cn; 
       cmd.CommandType = CommandType.StoredProcedure; 

       cmd.CommandText = "sp_InsertInDatabase"; 
       SqlParameterCollection cmdParams = cmd.Parameters as SqlParameterCollection; 
       cmdParams.AddWithValue("@param1", dt); 
       cmd.ExecuteNonQuery(); 
      } 
    } 
} 

En proyecto de prueba Unidad:

protected override IDbConnection GetConnection(string connectionString) 
    { 
     return Mock.Of<IDbConnection>(); 
    } 

    protected override IDbCommand GetCommand(IDbConnection cn) 
    { 
     return Mock.Of<IDbCommand>(); 
    } 

    protected override IDbTransaction GetTransaction(IDbConnection cn) 
    { 
     return Mock.Of<IDbTransaction>(); 
    } 

    public void TestInsertInDatabase() 
    { 
     base.InsertInDatabase(new DataTable()); 
    } 

--Solution--

Creado un método de extensión para añadir parámetro con valor. Gracias Marc Gravell por señalarme esa dirección.

public static IDbDataParameter AddParameterWithValue(this IDbCommand cmd, string paramName, object paramValue) 
    { 

     var dbParam = cmd.CreateParameter(); 
     if (dbParam != null) 
     { 
      dbParam.ParameterName = paramName; 
      dbParam.Value = paramValue; 
     } 
     return dbParam; 

    } 
+0

Es posible que desee llamar .Parameters.Add con el parámetro de nueva creación, ya que se espera con una Agregar método –

Respuesta

7

Personalmente, me acerco a este problema escribiendo un método AddParameterWithValue extensión a DbCommand (o IDbCommand). Tiene que estar en el comando para que tenga acceso al CreateParameter, y luego llame al .Parameters.Add.

Esto permite un fácil uso en cualquier pila de ADO.NET, incluidas las abstracciones como los decoradores de registro.

+0

suena interesante. – Asdfg

+0

@Asdfg Creo que dejé una versión de esto en "dapper" si la necesitas –

+0

Eso será genial. Estoy escribiendo el método de extensión, pero estoy luchando allí. – Asdfg

1

@Asdfg HI que básicamente han burlado de la colección de parámetros de la siguiente manera

string connectionString = "connectionstring"; 
     var sqlConnection = new SqlConnection(connectionString); 
     var command = sqlConnection.CreateCommand(); 
     //****************Setup Mock************************// 
     Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Data.SqlClient.SqlClientPermissionAttribute)); 
     var mockDataReader1 = new Mock<IDataReader>(); 
     command.Parameters.Add(new SqlParameter("@po_tint_Result", 1)); 
     //setup read return value 
     Queue<bool> responseQueue = new Queue<bool>(); 
     responseQueue.Enqueue(true); 
     responseQueue.Enqueue(false); 
     mockDataReader1.Setup(a => a.Read()).Returns(() => responseQueue.Dequeue()); 
     var mockDb = new Mock<SqlDatabase>(connectionString); 
     mockDb.Setup(a => a.GetStoredProcCommand("SPNAME")).Returns(command); 
     mockDb.Setup(a => a.ExecuteNonQuery(command)); 
     obj1.DbConn = mockDb.Object; 
     //*************************************************// 

espero que esto ayude

Cuestiones relacionadas