在C#中使用起订量嘲讽 [英] Mocking using Moq in c#
问题描述
我有以下代码:
公共接口IProductDataAccess
{
布尔CreateProduct(产品展示新品推荐);
}
类 ProductDataAccess
工具该接口。
公共类ProductBusiness
{
公共BOOL CreateProduct(产品展示新品推荐)
{
IProductDataAccess PDA =新ProductDataAccess();
布尔结果= pda.CreateProduct(新品展示);
返回结果;
}
}
在这种情况下,如何为创建单元测试 CreateProduct
以嘲讽 IProductDataAccess
接口方法?我想在 ProductBusiness
有 IProductDataAccess
的一个公网实例和使用初始化的模拟< IProductDataAccess> ;
对象,但它不是暴露在UI层的数据访问一个很好的做法。任何一个能帮助我吗?
经典的例子说明如何,如果你不能单元测试特定组件,重构组件<! / p>
这就是爱了任何模拟框架强制你做 - 写去耦代码
在你的榜样中, ProductBusiness
类是非常紧密耦合与 ProductDataAccess
。你可以用它(最喜欢的答案建议)依赖注入脱钩。通过这样做,你最终会取决于 IProductDataAccess
抽象比任何具体实施了。
另外一点要注意,当你写测试/规格为业务层,你通常要测试的行为,而不是国家。因此,尽管你可以有断言验证,如果真被退回,您的测试应该真正测试如果用起订量,我们实际使用最小起订量的.VerifyAPI执行。设定预期的数据访问调用
尝试添加在那里你期望一个抛出异常行为检测的数据访问层(使用.ThrowsAPI),并检查是否需要在业务层的任何特殊处理。
像凯文表明,有它看起来像ProductBusiness:
公开类ProductBusiness
{
私人只读IProductDataAccess _productDataAccess;
公共ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
公共BOOL CreateProduct(产品展示新品推荐)
{
布尔结果= _productDataAccess.CreateProduct(新品展示);
返回结果;
}
}
和使用任何的xUnit测试框架编写测试作为
VAR mockDataAccess =新的模拟< IProductDataAccess>();
mockDataAccess.Setup(M = GT; m.CreateProduct(It.IsAny<产品及GT;()))返回(真)。
变种productBusiness =新ProductBusiness(mockDataAccess.Object);
//行为进行测试
I have the following code:
public interface IProductDataAccess
{
bool CreateProduct(Product newProduct);
}
Class ProductDataAccess
implements that interface.
public class ProductBusiness
{
public bool CreateProduct(Product newProduct)
{
IProductDataAccess pda = new ProductDataAccess();
bool result = pda.CreateProduct(newProduct);
return result;
}
}
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 shows how if you cannot unit test a particular component, REFACTOR the component!
This is where is love what any mocking framework enforces you to do - write decoupled code.
In your example, the ProductBusiness
class is very tightly coupled with the ProductDataAccess
. 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 than any concrete implementation of it.
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, though 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 we actually executed using the ".Verify" API of MOQ.
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.
Like Kevin suggests, have the ProductBusiness which looks like:
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;
}
}
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#中使用起订量嘲讽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!