2016-04-04 25 views
0

Çalışabilirim, ancak en iyi uygulamanın ne olduğunu ve nedenini bilmek istiyorum. Bir Denetleyicim, bir Model ve bir Havuzum var ve şimdi Denetleyiciye Birim Testini istiyorum. Doğru görüntünün döndüğünden emin olmak için basit bir test yapıyorum.Birim Bir Denetleyiciyi Sınama - Bağlantı Dizesini Nasıl Kullanırım?

public ActionResult Selections(SelectionsViewModel model) 
    { 
     for (int i = 0; i < model.Sends.Count; i++) 
     { 
      Send send = new Send(new SendService(new Database().GetConnectionString())) 
      { 
       SendID = model.Sends[i].SendID, 
       Title = model.Sends[i].Title, 
       Subject = model.Sends[i].Subject, 
       SentDate = model.Sends[i].SentDate, 
       TimesViewed = model.Sends[i].TimesViewed, 
       Include = model.Sends[i].Include, 
       Exclude = model.Sends[i].Exclude 
      }; 
      send.UpdateIncludeExclude(); 
     } 

     return View(model); 
    } 

İşte benim SendService yapıcı aracılığıyla gönderiliyor Veritabanı sınıfta benim GetConnectionString() yöntemidir:

Bu denetleyici benim yöntemidir.

public string GetConnectionString() 
    { 
     return System.Configuration.ConfigurationManager.ConnectionStrings["DEVConnectionString"].ToString(); 
    } 

Ve son olarak, benim birim testi:

[Test] 
    public void TestAssignmentSelections() 
    { 
     var obj = new AssignmentController(); 

     var actResult = obj.Selections() as ViewResult; 

     NUnit.Framework.Assert.That(actResult.ViewName, Is.EqualTo("Selections")); 
    } 

Şimdi benim birim test başarısız olur ve neden olsun. Ünite test projem, bağlantı dizilimin bulunduğu yerde test ettiğim projenin web.config dosyasına erişemiyor.

Bazı araştırmalar yaptım ve görünüşe göre sadece bir web.config'i ünite test projeme ekledim ve bağlantı dizesini buraya yerleştirmek de işe yaratacaktır .. ama bu bir kesmek gibi görünüyor.

Bu konuda gitmenin en iyi yolu nedir? Kodumu buna uygun olarak yazmanın başka bir yolu var mı?

cevap

3

Kontrol ünitenizi test edilebilir hale getirmek ister misiniz? Bunu yapma. Bu kod ile

new SendService(

, size somut servis uygulaması & veri erişim kodu uygulaması hardcoding edilmektedir. Ünite testinizde, veritabanınızdan gerçekten veriye erişmemelisiniz. Bunun yerine bir sahte veri erişimi uygulaması sağlamalısınız.

İşte arayüzler geliyor, sizin SendService için bir arayüz oluşturmalısınız.

public interface ISendService 
{ 
    void SomeMethod(); 
} 

şimdi senin SendService Bu arayüz

public class SendService : ISendService 
{ 
    public void SomeMethod() 
    { 
    // Do something 
    } 
} 
Şimdi

biz ISendService bir uygulamasını enjekte edecek bir kurucu sahip olmasını denetleyici güncellemek somut bir uygulama olacaktır.

public class YourController : Controller 
{ 
    private ISendService sendService; 
    public YourController(ISendService sendService) 
    { 
    this.sendService = sendService; 
    }  
    public ActionResult YourActionMethod() 
    { 
    // use this.sendService.SomeMethod(); 
    } 
} 

Ve kod çalıştığında arayüzünün uygulanması kullanmak MVC framework anlatmak için bazı bağımlılık enjeksiyon çerçeveler kullanabilir. MVC6 kullanıyorsanız, kullanabileceğiniz bir dahili bağımlılık enjeksiyon sağlayıcısı var. Dolayısıyla, Startup sınıfınıza gidin ve ConfigureServices yönteminizde bir arabirimi somut bir uygulamaya eşleştirebilirsiniz. Eğer MVC önceki bir sürümünde ise

public class Startup 
{ 
    public void ConfigureServices(IServiceCollection services) 
    { 
    services.AddTransient<ISendService, SendService>(); 
    } 
} 

, Sen daha sonra Veri erişimi/Servis katmanları için aynı yaklaşımı yapabilir Unity, Ninject vb DI çerçeveler düşünebiliriz. Yani: Veri erişimi için bir arayüz oluşturun ve SendService'inize bunu enjekte edin.

public Interface IDataAccess 
{ 
    string GetName(int id); 
} 

ve spesifik veri erişim kodunu kullanan bir uygulama/ORM

public class EFDataAccess : IDataAccess 
{ 
    public string GetName(int id) 
    { 
    // return a string from db using EF 
    } 
} 

Yani şimdi Servis sınıf bir alay oluşturabilir, sizin birim testlerinde

public class SendService : ISendService 
{ 
    private IDataAccess dataAccess; 
    public SendService(IDataAccess dataAccess) 
    { 
    this.dataAccess=dataAccess; 
    } 
    // to do : Implement methods of your ISendService interface. 
    // you may use this.dataAccess in those methods as needed. 
} 

olacak Veritabanlarına erişmek yerine, statik verileri döndüren arabirimlerinizin uygulanması. Örneğin, Moq alay çerçevesini kullanıyorsanız, bunu yapabilirsiniz.

var m = new Mock<IDataAccess>(); 
var m.Setup(s=>s.GetName(It.IsAny<int>())).Returns("Test"); 
var s = new SendService(m); 
var result= s.SomeMethod(); 
+0

Bu yardımcı oldu, bence bazı değişiklikler yapacağım. Teşekkür ederim. – halterdev

İlgili konular