我有以下代码:
public interface IProductDataAccess
{
bool CreateProduct(Product newProduct);
}
类 ProductDataAccess 实现该接口.
public class ProductBusiness
{
public bool CreateProduct(Product newProduct)
{
IProductDataAccess pda = new ProductDataAccess();
bool result = pda.CreateProduct(newProduct);
return result;
}
}
在这种情况下,如何通过模拟 IProductDataAccess 接口为 CreateProduct 方法创建单元测试?我想在 ProductBusiness 中有一个 IProductDataAccess 的公共实例并使用 Mock 对象对其进行初始化,但公开它不是一个好习惯对 UI 层的数据访问.谁能帮帮我?
In this case, how to create unit test for CreateProduct method by mocking the IProductDataAccess interface? I thought of having an public instance of IProductDataAccess within ProductBusiness and initialize it using Mock<IProductDataAccess> object but it is not a good practice to expose the data access to the UI layer. Can any one help me?
经典示例演示如果您无法对特定组件进行单元测试,请对其进行重构!
Classic example which demonstrates that if you cannot unit test a particular component, REFACTOR it!
这就是为什么我喜欢任何模拟框架强制您执行的操作 - 编写解耦代码.
This is why I love what any mocking framework enforces you to do - write decoupled code.
在您的示例中,ProductBusiness 类与 ProductDataAccess 类紧密耦合.您可以使用(就像大多数答案建议的那样)依赖注入来解耦它.通过这样做,您最终将依赖于 IProductDataAccess 抽象,而不是依赖于它的任何具体实现.
In your example, the ProductBusiness class is tightly coupled with the ProductDataAccess class. You could decouple it using (like most of the answers suggest) dependency injection. By doing so, you would end up depending on the IProductDataAccess abstraction and not on any concrete implementation of it.
还有一点需要注意,当您为业务层编写测试/规范时,您通常希望测试行为"而不是状态".因此,尽管您可以断言验证是否返回true",但您的测试应该真正测试使用 MOQ 设置的预期数据访问调用是否实际使用 MOQ 的 .Verify API 执行.
Another point to note, when you are writing tests/specifications for the business layer, you would typically want to test the "behavior" and not the "state". So, although you could have asserts that verify if "true" was returned, your tests should really test if the expected data access calls that were set using MOQ were actually executed using the .Verify API of MOQ.
尝试在您希望数据访问层抛出异常(使用.Throws"API)的地方添加行为测试,并检查您是否需要在业务层进行任何特殊处理.
Try adding behavior tests where you expect an exception to be thrown (using the ".Throws" API) by the data access layer and check if you need any special handling at the business layer.
就像 Kevin 建议的那样,ProductBusiness 的以下实现将起作用:
Like Kevin suggests, the following implementation of ProductBusiness will work:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result=_productDataAccess.CreateProduct(newProduct);
return result;
}
}
并使用任何 xunit 测试框架将测试编写为:
and use any xunit testing framework to write the test as:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess.Setup(m => m.CreateProduct(It.IsAny<Product>())).Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
//behavior to be tested
这篇关于在 c# 中使用 Moq 进行模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
ASP.NET Core 使用 Azure Active Directory 进行身份验证并ASP.NET Core authenticating with Azure Active Directory and persisting custom Claims across requests(ASP.NET Core 使用 Azure Active Directory 进行身
ASP.NET Core 2.0 Web API Azure Ad v2 令牌授权不起作用ASP.NET Core 2.0 Web API Azure Ad v2 Token Authorization not working(ASP.NET Core 2.0 Web API Azure Ad v2 令牌授权不起作用)
如何获取守护进程或服务器到 C# ASP.NET Web API 的How do I get Azure AD OAuth2 Access Token and Refresh token for Daemon or Server to C# ASP.NET Web API(如何获取守护进程或服务器到 C# ASP.N
异步调用时 Azure KeyVault Active Directory AcquireTokenAAzure KeyVault Active Directory AcquireTokenAsync timeout when called asynchronously(异步调用时 Azure KeyVault Active Directory AcquireTokenAsync 超
使用电子邮件地址和应用程序密码从 oauth2/tokenGetting access token using email address and app password from oauth2/token(使用电子邮件地址和应用程序密码从 oauth2/token 获取访问令
新的 Azure AD 应用程序在通过管理门户更新之前无New Azure AD application doesn#39;t work until updated through management portal(新的 Azure AD 应用程序在通过管理门户更新之前无法运行