我正在考虑有关可测试性的“最佳实践”以及定义特定操作的最佳方式。
在 SportsStore 应用程序(来自 Pro ASP.NET MVC 4)中,对于 AdminController,我们在 AdminController.cs 文件中有以下两个方法:
产品资料库
namespace SportsStore.Domain.Abstract {
public interface IProductRepository {
IQueryable<Product> Products { get; }
void SaveProduct(Product product); //Defined in EFProductRepository
void DeleteProduct(Product product); //Defined in EFProductRepository
}
}
管理员控制器:
private IProductRepository repository;
public ViewResult Edit(int productId) {
Product product = repository.Products.FirstOrDefault(p => p.ProductID == productId);
...
}
[HttpPost]
public ActionResult Delete(int productId) {
Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId);
...
}
正如我所注意到的,我们基本上是在做同样的逻辑,那就是找到 productID。如果 productId 完全改变,改变为别的东西,我们需要在两个地方改变它。不过,这可以很容易地进行测试,因为控制器本身正在进行 Linq 调用。
我在想我可以把它放到 EFProducts 的等效项中(所以 IProducts 接口的数据库实现),但这会创建与某种数据库状态的联系。我想在我的单元测试中避免这种情况,因为它会相当多地增加测试复杂性。
有没有更好的地方来放置这个 FindOrDefault 逻辑,而不是放在控制器中,同时保持大量的可测试性?
Edit1:添加存储库的定义,它指向一个接口