我已经创建了一个Web API,并为此开发了一些单元测试。在我的一个控制器中,我传入一个Id变量,该变量运行存储过程并返回具有匹配数据的数据列表。这是我的单元测试之一:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Http.Results;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebApi.Controllers;
using WebApi.Models;
namespace UnitTestProject1
{
[TestClass]
public class ProductContollerTests
{
// Unit Test Description: Tests to check the number of returned items with the BrandId = 1 matches the number of Products In testProducts
[TestMethod]
public void GetProducts_ShouldRetrunCorrectProducts()
{
var testProducts = GetTestProducts();
var controller = new ProductsController(testProducts);
var result = controller.GetProducts(1) as List<Product>;
Assert.AreEqual(testProducts.Count, result.Count);
}
private List<Product> GetTestProducts()
{
var testProducts = new List<Product>
{
new Product { BrandId = 1, ProductId = 1, ProductName = "Home" },
new Product { BrandId = 1, ProductId = 2, ProductName = "Motor" },
new Product { BrandId = 1, ProductId = 3, ProductName = "Travel" },
new Product { BrandId = 1, ProductId = 4, ProductName = "Van" },
new Product { BrandId = 1, ProductId = 5, ProductName = "Commercial" }
};
return testProducts;
}
}
}
当前正在通过,因为我要对返回的数据进行计数并进行比较,以查看它是否等于列表testproducts中的数据。当前,这是在品牌ID等于1时的单元测试。但是,如果我想在品牌ID等于2时进行测试,会发生什么?
我可以将新产品添加到testProducts列表中,但这会导致第一个测试失败,因为我正在计算testProducts列表中的元素,因此当我添加其他产品时,例如
new Product { BrandId = 2, ProductId = 6, ProductName = "Creditor" }
testProducts中的值多于从我的API返回的数据。有没有一种我可以添加它的方式,以便我只计算brandId为1的元素,以便可以添加其他测试,或者在测试不同的东西时必须始终创建新的测试产品列表。
您正在告诉该控制器使用五种产品的列表,然后当您调用ID为1的get方法时(您甚至没有使用过该ID时),您确认可以收回5种产品。
这是没有意义的测试,您没有测试任何东西。相反,这是我会做的:
我会在一个实际的数据库中创建一个真实的项目列表,然后调用get品牌终结点并验证我是否应该恢复。这将是一个集成测试,它告诉您多个端点都在工作。
单元测试是关于功能,按照明确定义的方法,以明确的输入和输出,以某种方式更改某些数据。
我还将摆脱实例化控制器的想法,以在其内部调用方法,而是创建适当的层并对其进行测试。这就像以Webforms方式构建现代API。