2009-08-21 3 views
-1

Я читаю Asp.net MVC Framework, и я читаю об IDataErrorInfo как форме проверки.Как модульный тест IDataErrorInfo?

Так что я просто собираюсь опубликовать то, что у него есть.

Продукт класса

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 

namespace MvcApplication1.Models 
{ 
    public partial class Product : IDataErrorInfo 
    { 

     private Dictionary<string, string> _errors = new Dictionary<string, string>(); 

     partial void OnNameChanging(string value) 
     { 
      if (value.Trim() == String.Empty) 
       _errors.Add("Name", "Name is required."); 
     } 


     partial void OnPriceChanging(decimal value) 
     { 
      if (value <= 0m) 
       _errors.Add("Price", "Price must be greater than 0."); 
     } 


     #region IDataErrorInfo Members 

     public string Error 
     { 
      get { return string.Empty; } 
     } 

     public string this[string columnName] 
     { 
      get 
      { 
       if (_errors.ContainsKey(columnName)) 
        return _errors[columnName]; 
       return string.Empty; 
      } 
     } 

     #endregion 


    } 
} 

ProductRepository.

using System.Collections.Generic; 
using System.Linq; 

namespace MvcApplication1.Models 
{ 
    public class ProductRepository : IProductRepository 
    { 
     private ProductsDBEntities _entities = new ProductsDBEntities(); 

     public IEnumerable<Product> ListProducts() 
     { 
      return _entities.ProductSet.ToList(); 
     } 

     public void CreateProduct(Product productToCreate) 
     { 
      _entities.AddToProductSet(productToCreate); 
      _entities.SaveChanges(); 
     } 

    } 

    public interface IProductRepository 
    { 
     IEnumerable<Product> ListProducts(); 
     void CreateProduct(Product productToCreate); 
    } 
} 

Контроллер

using System.Web.Mvc; 
using MvcApplication1.Models; 

namespace MvcApplication1.Controllers 
{ 
    public class ProductController : Controller 
    { 
     private IProductRepository _repository; 

     public ProductController() 
      :this(new ProductRepository()){} 


     public ProductController(IProductRepository repository) 
     { 
      _repository = repository; 
     } 


     public ActionResult Index() 
     { 
      return View(_repository.ListProducts()); 
     } 


     // 
     // GET: /Product/Create 

     public ActionResult Create() 
     { 
      return View(); 
     } 

     // 
     // POST: /Product/Create 

     [AcceptVerbs(HttpVerbs.Post)] 
     public ActionResult Create([Bind(Exclude="Id")]Product productToCreate) 
     { 
      if (!ModelState.IsValid) 
       return View(); 
      _repository.CreateProduct(productToCreate); 
      return RedirectToAction("Index"); 
     } 


    } 
} 

Но нет, где в книге я вижу, как на самом деле это модульное тестирование. Подобно тому, как он показывает вам, как выполнить модульное тестирование своего уровня сервисного уровня, но ничего о модульном тестировании IDataErrorInfo.

Итак, как я могу это проверить? Мне нравится проверять сообщения об ошибках, чтобы убедиться, что они одинаковые. Например, если я передаю пустое поле, мне нравится проверять, будет ли сообщение об ошибке правильным для этого нулевого поля.

После того, как мне нравится проверять логику оператора после того, как материал должен быть проверен, чтобы убедиться, что он делает то, что ожидается, но я даже не знаю, как назвать этот частичный класс особенно тем, что вы обычно не используете хотите попасть в базу данных при выполнении модульных тестов.

+1

Класс продукта, который вы опубликовали, является частичным. Должна быть одна или несколько дополнительных реализаций класса Product, которые (среди прочего) вызывают частичные методы. Ответ на ваш вопрос не так-то просто, когда мы не знаем, как это выглядит. Кроме того, я не вижу, как с этим связаны Репозиторий и Контроллер, так что, возможно, вы можете решить свой вопрос? –

ответ

1

Модульное тестирование IDataErrorInfo довольно простое. Просто установите ваши тесты с «действительным» экземпляром объекта, а затем проверить, что вы можете сделать это сообщение об ошибке:

[TestFixture] 
public class ErrorTests 
{ 
    private Product _product; // subject under test 

    [SetUp] 
    public void Create_valid_instance() 
    { 
     _product = new Product { /* valid values */ }; 
    } 

    [Test] 
    public void Name_cannot_be_null() 
    { 
     _product.Name = null; 
     Assert.AreEqual("Name is required.", _product.Error); 
     Assert.AreEqual("Name is required.", _product["Name"]); 
    } 

    [Test] 
    public void Name_cannot_be_empty() 
    { 
     _product.Name = String.Empty; 
     Assert.AreEqual("Name is required.", _product.Error); 
     Assert.AreEqual("Name is required.", _product["Name"]); 
    } 

    [Test] 
    public void Name_cannot_be_whitespace() 
    { 
     _product.Name = " "; 
     Assert.AreEqual("Name is required.", _product.Error); 
     Assert.AreEqual("Name is required.", _product["Name"]); 
    } 

    /* etc - add tests to prove that errors can occur */ 
} 
+1

Это не похоже на правду. Индекс ошибок (этот []) появляется только в моем приложении, когда я включаю ValidatseOnDataErrors в свой xaml. В моем тестовом приложении, которому, похоже, не хватает места, чтобы включить это, индекс индексации ошибок никогда не проверяется на моих бизнес-объектах IDataErrorInfo. Итак, установите myObject.Name = string.Empty; никогда не будет проверять правило имени. Я все еще ищу способ сделать это. – Bob

+0

Согласитесь с Боб. Это не полностью работает ... – CamronBute

+1

Итак, мы ясно: я публикую некоторые тесты, и потому что вы не можете заставить их пройти, вы даете мне downvotes? Верните ошибку из свойства Error, а также индексатора! Затем проходят тесты! –

2

Решение упоминается Matt работает только для меня, если я использую позже заявление Утверждает -

Assert.AreEqual («Name is required.», _product [«Name»]); - это работает для меня

Assert.AreEqual («Name is required.», _product.Error); - это не работает для меня