2016-08-15 39 views
6

Geçmişte, birim sınama uygularken, veri erişimi katmanları için 'dürüst' birim sınamaları oluşturmak için çaba harcadım çünkü çoğu zaman bir dış bağımlılık olarak bir veritabanına sahipler. İdeal bir dünyada, saklı yordam çağrıları ile dış bağımlılığın ortadan kaldırılması için uğraşırdım. Bununla birlikte, MOQ alay çerçevesini kullanarak bunun nasıl yapılacağını ya da bunu destekleyen başka bir çerçeve bulmayı başaramadım. Bunun yerine, bilinen veriye sahip betikli bir test veritabanı oluşturmaya geri döndüm (böylece her zaman beklediğim çıktıları elde edebilirim), ancak bu katman Alay etmekten biraz farklıdır.C# birim sınama, saklı yordam yordamı

Veri erişim katmanının [https://effort.codeplex.com/'un var olduğu Varlık Çerçevesi için biliyorum] bu kısmının Nasıl Yapılacağını önerebilecek herhangi biri var mı? Örneğin


Detay I SQLDataReader belirtilen verileri içerir, böylece saklı yordam çıkış dalga nasıl aşağıdaki yöntem

public object RunStoredProc() 
{ 
    //Some Setup 

    using (SqlConnection conn = new SqlConnection(CONNNECTION_STRING)) 
    { 
     using (SqlCommand comm = new SqlCommand("storedProcName", conn)) 
     { 
      conn.Open(); 
      comm.CommandType = CommandType.StoredProcedure; 
      using (SqlDataReader reader = comm.ExecuteReader()) 
      { 
       while (reader.Read()) 
       { 
        //Logic 
       } 
      } 
     } 
    } 

    //Return object based on logic 
} 

varsa. Daha yüksek bir seviyede RunStoredProc() yöntemini alay edebildim, ancak bu yöntemdeki mantığın doğru olup olmadığını test etmeme yardımcı olmaz. Alternatif başka bir yöntem haline dışarı SQLReader şerit olabilir

public object RunStoredProc() 
{ 
    //Some Setup 

    List<object> data = GetData(); 
    //Logic 

    //Return object based on logic 
} 

private List<object> GetData() 
{ 
    using (SqlConnection conn = new SqlConnection(CONNNECTION_STRING)) 
    { 
     using (SqlCommand comm = new SqlCommand("storedProcName", conn)) 
     { 
      conn.Open(); 
      comm.CommandType = CommandType.StoredProcedure; 
      using (SqlDataReader reader = comm.ExecuteReader()) 
      { 
       while (reader.Read()) 
       { 
        //place into return object 
       } 
      } 
     } 
    } 
} 

ama 'Getdata' yöntemi Sonra o alay etmek mümkün olmaz (yayımlanmış arabiriminin parçası değil) özel olması gerektiği gibi ve bu yüzden sorun kalıntıları

.

cevap

3

bugün geldikleri alay ve Bağımlılık Enjeksiyon ile kullanılabilir, böylece gerekli soyut her şeyin tüm arayüzleri (IDbConnection, IDbTransaction, IDbCommand, IDataReader) ve EF (IDbConnectionFactory) dan bir fikir ödünç var. Bence SqlConnection ve geri kalanı daha fazla uygulama detayı ve soyutlanabilir. Eğer bir bağlantı fabrika

public interface IDbConnectionFactory { 
    /// <summary> 
    /// Creates a connection based on the given database name or connection string. 
    IDbConnection CreateConnection(string nameOrConnectionString); 
} 

oluşturabilir Ve sonra sadece soyutlamalar kullanmak için örnek yöntemi planı ayrı İdare Framework bir fikir ardından

.

public class MyDataAccessClass { 
    private IDbConnectionFactory dbConnectionFactory; 
    private string CONNNECTION_STRING = "Connection string here"; 

    public MyDataAccessClass(IDbConnectionFactory dbConnectionFactory) { 
     this.dbConnectionFactory = dbConnectionFactory; 
    } 

    public object RunStoredProc() { 
     //Some Setup 
     List<object> result = new List<object>(); 

     using (IDbConnection conn = dbConnectionFactory.CreateConnection(CONNNECTION_STRING)) { 
      using (IDbCommand comm = conn.CreateCommand()) { 
       comm.CommandText = "storedProcName"; 
       conn.Open(); 
       comm.CommandType = CommandType.StoredProcedure; 
       using (IDataReader reader = comm.ExecuteReader()) { 
        while (reader.Read()) { 
         //...Logic to populate result 
        } 
       } 
      } 
     } 

     //Return object based on logic 
     return result; 
    } 
} 

Buradan seçtiğiniz Alaycı çerçevesini kullanarak arayüzleri alay veya enjekte ve yöntemi test etmek için kendi sahte oluşturun. bu ödeme şekli gibi ben IDbCommand.ExecuteReader() olacağını alay gerekiyordu bu doğru tek yöntemi okuyorum eğer

[TestClass] 
public class StoredProcedureUnitTest { 
    [TestMethod] 
    public void TestRunStoredProc() { 
     //Arrange 
     var connectionFactory = new Mock<IDbConnectionFactory>(); 
     //..Setup... 

     var sut = new MyDataAccessClass(connectionFactory.Object); 

     //Act 
     var actual = sut.RunStoredProc(); 

     //Assert 
     //... 
    } 
} 
+0

sayesinde [I ayrıca IDbConnection.CreatCommand alay etmek gerekirdi görünüyor alay IDbCommand döndürmek ama bu önemsiz olmalıdır]. Bir başkasının başka fikirleri varsa, bir süreliğine soruyu açık bırakacağım. –

İlgili konular