8

Scott Guthrie'nin ASP.NET MVC Beta 1 numaralı telefonunda mükemmel bir şekilde çalışıyorum. İçinde UpdateModel yönteminde yapılan geliştirmeleri ve birim testini nasıl geliştirdiğini gösterir. Benzer bir projeyi yeniden oluşturdum ancak UpdateModel'e bir çağrı içeren bir UnitTest çalıştırdığımda controllerContext parametresini adlandıran bir ArgumentNullException alıyorum. UpdateModel'i kullanan alay edilmeden Birim Test İşlemlerini nasıl yapabilirim?

public class Country { 
    public Int32 ID { get; set; } 
    public String Name { get; set; } 
    public String Iso3166 { get; set; } 
} 

denetleyici eylem

: başarısız oluyor

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Int32 id, FormCollection form) 
{ 
    using (ModelBindingDataContext db = new ModelBindingDataContext()) { 
    Country country = db.Countries.Where(c => c.CountryID == id).SingleOrDefault(); 

    try { 
     UpdateModel(country, form); 

     db.SubmitChanges(); 

     return RedirectToAction("Index"); 
    } 
    catch { 
     return View(country); 
    } 
    } 
} 

Ve nihayet birim testi:

[TestMethod] 
public void Edit() 
{ 
    CountryController controller = new CountryController(); 
    FormCollection form = new FormCollection(); 
    form.Add("Name", "Canada"); 
    form.Add("Iso3166", "CA"); 

    var result = controller.Edit(2 /*Canada*/, form) as RedirectToRouteResult; 

    Assert.IsNotNull(result, "Expected to be redirected on successful POST."); 
    Assert.AreEqual("Show", result.RouteName, "Expected to redirect to the View action."); 
} 

ArgumentNullException atılır

İşte benim modeli ile başlayan alakalı bit var "Değer, null. P" mesajıyla UpdateModel numaralı çağrı ile arametrenin adı: controllerContext ". Ben UpdateModel bir yerde testin yürütülmesi sırasında mevcut olmayan System.Web.Mvc.ControllerContext gerektirir varsayalım.

Ayrıca bir yerde yanlış bir şey yaptığımı ve sadece doğru yönde işaret etmem gerektiğini varsayarım.

Yardım Lütfen!

cevap

5

Bu, UpdateModel'in kullandığı TryUpdateModel'den beri, bir birim testinden çağrıldığında null olan ControllerContext'e başvurduğundan emin değilim. Kontrolörün ihtiyaç duyduğu çeşitli bileşenleri alay etmek veya saplamak için RhinoMocks'ı kullanırım.

protected internal bool TryUpdateModel<TModel>(...) where TModel : class 
{ 

    .... 

    ModelBindingContext bindingContext = 
      new ModelBindingContext(ControllerContext, 
            valueProvider, 
            typeof(TModel), 
            prefix, 
            () => model, 
            ModelState, 
            propertyFilter); 

    ... 
} 
+1

Katılıyorum, bunu alay ederek çözebilirim, ancak Scott'ın PostModel örneklerine atıfta bulunarak Scott'ın söylediklerine açıkça karşı çıkıyor: "Yukarıdaki form teslim senaryolarının her ikisini de birim testine bir şeyle uğraşmak zorunda kalmadık. " –

+0

TryUpdateModel (hangi UpdateModel'in kullandığı) kaynağına baktım ve kesinlikle ControllerContext kullanıyor. Yanıtımı, kaynak kodu biti ile güncelledim. – tvanfosson

+0

@Hellfire, blog yayınında en az bir başka kişinin aynı hatayı aldığını belirten bir yorum gördüm. Beta 1'in kapıdan çıkmasından önce ModelBindingContext değişmiş olabilir. – tvanfosson

0

Yoksa form verilerini vekil oluşturabilir,

public class CountryEdit { 
    public String Name { get; set; } 
    public String Iso3166 { get; set; } 
} 

    gibi:

    var routeData = new RouteData(); 
    var httpContext = MockRepository.GenerateStub<HttpContextBase>(); 
    FormCollection formParameters = new FormCollection(); 
    
    EventController controller = new EventController(); 
    ControllerContext controllerContext = 
        MockRepository.GenerateStub<ControllerContext>(httpContext, 
                    routeData, 
                    controller); 
    controller.ControllerContext = controllerContext; 
    
    ViewResult result = controller.Create(formParameters) as ViewResult; 
    
    Assert.AreEqual("Event", result.Values["controller"]); 
    Assert.AreEqual("Show", result.Values["action"]); 
    Assert.AreEqual(0, result.Values["id"]); 
    

    İşte www.codeplex.com/aspnet üzerinde Controller.cs kaynağından alakalı biraz

  • Plus. Kolay kullanım ünitesi testleri
  • Plus.
  • Plus adresinden alanların beyaz listesini güncelleyin. Kolay kurulum doğrulama kuralları, kolay test edin.
  • Eksi. Eğer Yani Controller.Action görünmelidir

model Sen

public ActionResult Edit(Int32 id, CountryEdit input) 
{ 
    var Country = input.ToDb(); 
    // Continue your code 
} 
2

Bu aynı sorunu geçiriyormuş gibi, proxy'den tarihini hareket etmelidir. Tvanfosson çözümünü okuduktan sonra, sahte bir çerçeveyi içermeyen basit bir çözüm denedim.

CountryController controller = new CountryController(); 
controller.ControllerContext = new ControllerContext(); 

Bu birim test ederken benim için sadece iyi hata kaldırıldı şu şekildedir:

kontrolöre varsayılan bir ControllerContext ekleyin. Umarım bu, başka birine yardım edebilir.

İlgili konular