大家好,我对单元测试很新。我的方案:我有一个产品业务逻辑层,在add / update等产品服务方法中有以下类和接口(product
,productCategory
,接口IProductRepository
,ProductService
) /删除已实现。我想在添加产品时编写单元测试。下面是我的代码,但我不确定我是否正确执行。
测试方案
1)当我添加新产品时检查过期日期是否大于当前日期
2)当我添加新产品时,价格必须大于0
3)不要添加删除标志设置为false的产品
4)当我添加产品类别名称时,不应该为空/空白
我真的很感激,如果有人可以指出我正确的方向,特别是在断言方面。 代码
在ProductService类中保存方法
public Boolean save(Product product)
{
Boolean flg = false;
if ( (product.Expire > DateTime.Now && product.Price > 0 )
&& (product.flg =true))
{
flg = true;
}
return flg;
}
单元测试
[TestClass()]
public class ProductServiceTests
{
ProductService Objproductservice;
List<Product> ProductList;
Product product1;
Product product2;
Product product3;
DateTime time;
Boolean flg;
[TestInitialize]
public void Setup()
{
flg = false;
product1 = new Product { ProductId = 1, Name = "Ice Cream Ben&Jerry", Description = "Dairy", Expire = DateTime.Now.AddDays(20), DateModified = DateTime.Now, Price = 3.99, flg = true, CatID=2, CategoryName="Dairy" };
product2 = new Product { ProductId = 1, Name = "Rice Basmati", Description = "Grocery", Expire = DateTime.Now.AddDays(20), DateModified = DateTime.Now, Price = 7.99, flg = false, CatID = 1002, CategoryName = "Grocery" };
}
[TestMethod]
public void when_save_product_expire_date_greater_current_date()
{
Objproductservice = new ProductService();
flg = Objproductservice.save(product1);
Assert.IsTrue(product1.Expire > DateTime.Now);
Assert.IsTrue(flg);
}
[TestMethod()]
public void when_save_product_price_greater_than_zero()
{
Objproductservice = new ProductService();
flg = Objproductservice.save(product1);
Assert.IsTrue(product1.Price > 0);
Assert.IsTrue(flg);
}
[TestMethod]
public void do_not_save_product_if_delete_flg_isFalse()
{
Objproductservice = new ProductService();
flg = Objproductservice.save(product2);
Assert.IsFalse(product2.flg);
Assert.IsFalse(flg);
}
[TestMethod]
public void when_add_product_stock_level_increate()
{
}
[TestMethod]
public void when_save_product_categoryName_should_not_be_null()
{
Objproductservice = new ProductService();
flg = Objproductservice.save(product1);
string CategoryName = product1.CategoryName;
Assert.IsTrue(CategoryName.Length > 0);
Assert.IsTrue(flg);
}
}
答案 0 :(得分:3)
我建议您遵循Tell Don't Ask原则,而不是要求产品的到期日期,价格等 - 告诉他自己检查(顺便说一句,IsExpired可以,但考虑禁止将无效价格设置为产品):
public class Product
{
public DateTime Expire { get; set; }
public decimal Price { get; set; }
public virtual bool IsExpired
{
get { return Expire > DateTime.Now; }
}
public virtual bool IsValid
{
get { return !IsExpired && Price > 0; }
}
}
现在您可以创建过期或价格无效的不同产品并将其传递给服务:
ProductService service;
Mock<IProductRepository> repositoryMock;
Mock<Product> productMock;
[TestInitialize]
public void Setup()
{
repositoryMock = new Mock<IProductRepository>();
service = new ProductService(repositoryMock.Object);
productMock = new Mock<Product>();
}
[TestMethod]
public void Should_not_save_invalid_product()
{
productMock.SetupGet(p => p.IsValid).Returns(false);
bool result = service.save(productMock.Object);
Assert.False(result);
repositoryMock.Verify(r => r.Save(It.IsAny<Product>()),Times.Never());
}
[TestMethod]
public void Should_save_valid_product()
{
productMock.SetupGet(p => p.IsValid).Returns(true);
repositoryMock.Setup(r => r.Save(productMock.Object)).Returns(true);
bool result = service.save(productMock.Object);
Assert.True(result);
repositoryMock.VerifyAll();
}
服务的实施如下:
public bool save(Product product)
{
if (!product.IsValid)
return false;
return repository.Save(product);
}
接下来编写Product测试以验证IsValid是否正常工作。您可以使用允许模拟静态成员的单元测试框架(例如TypeMock),或者您可以使用Factory创建产品并向其注入ITimeProvider实现。那将允许你模拟时间提供者。或者很好的组合解决方案 - 创建自己的静态时间提供程序,允许设置值:
public static class TimeProvider
{
private static Func<DateTime> currentTime { get; set; }
public static DateTime CurrentTime
{
get { return currentTime(); }
}
public static void SetCurrentTime(Func<DateTime> func)
{
currentTime = func;
}
}
使用此提供商代替DateTime.Now
:
public virtual bool IsExpired
{
get { return Expire > TimeProvider.CurrentTime; }
}
现在您可以为产品提供当前时间和编写测试:
private DateTime today;
[TestInitialize]
public void Setup()
{
today = DateTime.Today;
TimeProvider.SetCurrentTime(() => today);
}
[TestMethod]
public void Should_not_be_valid_when_price_is_negative()
{
Product product = new Product { Price = -1 };
Assert.False(product.IsValid);
}
[TestMethod]
public void Should_be_expired_when_expiration_date_is_before_current_time()
{
Product product = new Product { Expire = today.AddDays(-1) };
Assert.False(product.IsExpired);
}
// etc