您能用非常简单的术语解释一下 Moq 在这里做什么吗?

发布于 2024-10-22 14:40:05 字数 1126 浏览 1 评论 0原文

这是我的 IProductRepository:

public interface IProductsRepository
{
    IQueryable<Product> Products { get; }
}

这是我使用 Moq 的地方:

public static IProductsRepository MockProductsRepository(params Product[] prods)
{
    var mockProductRepos = new Mock<IProductsRepository>();
    mockProductRepos.Setup(x => x.Products).Returns(prods.AsQueryable());
    return mockProductRepos.Object;
}

这是我如何使用这个 MockProductsRepository 方法:

[Test]
public void Product_Lists_Include_Correct_Page_Numbers()
{
    //Arrange: If there are five products in the repository...
    var mockRepository = UnitTestHelpers.MockProductsRepository(
        new Product { Name = "P1" }, new Product { Name = "P2" },
        new Product { Name = "P3" }, new Product { Name = "P4" },
        new Product { Name = "P5" }
    );

    var controller = new ProductsController(mockRepository) { PageSize = 3 };

    //yada yada yada...
}

Moq 到底在做什么?我正在关注 Pro ASP.Net MVC2 这本书,它向我传授了各种新的魔法,在我继续阅读之前,我想了解发生了什么 - 现在我只知道,“它不起作用”更多的。 :)

谢谢您的宝贵时间。

Here is my IProductRepository:

public interface IProductsRepository
{
    IQueryable<Product> Products { get; }
}

And here is where I'm using Moq:

public static IProductsRepository MockProductsRepository(params Product[] prods)
{
    var mockProductRepos = new Mock<IProductsRepository>();
    mockProductRepos.Setup(x => x.Products).Returns(prods.AsQueryable());
    return mockProductRepos.Object;
}

And here is how I use this MockProductsRepository method:

[Test]
public void Product_Lists_Include_Correct_Page_Numbers()
{
    //Arrange: If there are five products in the repository...
    var mockRepository = UnitTestHelpers.MockProductsRepository(
        new Product { Name = "P1" }, new Product { Name = "P2" },
        new Product { Name = "P3" }, new Product { Name = "P4" },
        new Product { Name = "P5" }
    );

    var controller = new ProductsController(mockRepository) { PageSize = 3 };

    //yada yada yada...
}

What exactly is Moq doing? I'm following the book Pro ASP.Net MVC2 and it's teaching all sorts of new wizardry to me, and before I continue reading, I'd like to understand what's going on - and right now I just know, "it works" nothing more. :)

Thank you for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

树深时见影 2024-10-29 14:40:06

在幕后,Moq 动态创建接口 IProductRepository 的实现,并使方法 Products 返回您在其中提供的 IQueryable Returns 方法。

我不确定它是如何工作的,但我认为它为您调用的函数创建了一个委托 Setup ,该委托返回给 Returns 的值代码>.

因此,您的测试代码返回一个实现 IProductRepository 接口的类,但它是一个动态创建的类,它的某些行为已重新路由以执行您指定的特定操作。然后,Moq 可以检查指定的事情是否已完成,以验证您的期望,或者如果您只对提供模拟数据感兴趣,则仅返回数据。

Behind the scenes, Moq is dynamically creating an implementation of your interface IProductRepository and making the method Products return the IQueryable<Product> you gave it in the Returns method.

I'm not certain of exactly how it works but I think it creates a delegate for the function you called Setup on which return the value given to Returns.

So your test code gets back a class which implements the IProductRepository interface but it is a dynamically created class which has had some behaviour rerouted to do specific things you have specified. Moq can then check that the specified things have been done, to validate your expectations, or just return the data if you are only interested in providing mock data.

不爱素颜 2024-10-29 14:40:05

Moq 正在内存中为实现 IProductsRepository 的类生成 IL,其所有属性/方法都会回调 Moq 以查看它应该执行的操作。 SetupProducts 属性配置为在调用时始终返回提供的产品列表(作为 IQueryable)。然后,它将生成的对象作为 IProductsRepository 返回,然后可以将其传递给 ProductsController,而后者对其动态性质一无所知。

Moq is generating the IL in memory for a class that implements IProductsRepository, with all its properties/methods calling back to Moq to see what it should do. The Setup is configuring the Products property to always return the supplied list of products (as an IQueryable) when it is called. It's then returning the generated object as a IProductsRepository which can then be passed to ProductsController which is none the wiser about its dynamic nature.

若沐 2024-10-29 14:40:05

模拟框架(以及其他一些 DI 框架)可以在运行时发出(通常使用Reflection.Emit),这是它们通常称为代理的接口的实现(尽管这个术语的含义有许多令人困惑的变化)。

对于模拟的情况,这将拦截对该接口的调用,并具有实现来检查您对它们设置的期望。

Mock frameworks (as well as some other DI frameworks) can emit on runtime (usually using Reflection.Emit), an implementation of an interface which they usually call proxy (although this term has many confusing variations in meaning).

For the case of a mock, this will intercept calls to that interface and has implementation to check the expectations you set upon them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文