.net 使用Moq等的好处

sczxawaw  于 2023-02-06  发布在  .NET
关注(0)|答案(4)|浏览(303)

我曾经遇到过一些关于使用Moq进行单元测试的参考资料。但是在看过moq的wiki例子之后,我真的看不到仅仅创建一个mock仓库有什么好处。我错过了一些东西吗?下面是我创建的一个mock仓库的例子。moq可以用任何方式优化它吗?

namespace Models
    {
        public class MockImagesRepository : IImagesRepository
        {
            private readonly BlogContext _context;
            private readonly List<ImageViewModel> _imageViewModels;

            public MockImagesRepository()
            {
                _context = new BlogContext();
                _imageViewModels = new List<ImageViewModel>();
                for (var i = 0; i < 10; i++)
                {
                    _imageViewModels.Add(new ImageViewModel
                                             {
                                                 Id = i,
                                                 AlternateText = "AlternateText " + i,
                                                 Description = "Description " + i,
                                                 Name = "Name " + i,
                                             });
                }
                for (var i = 10; i < 20; i++)
                {
                    _imageViewModels.Add(new ImageViewModel
                                             {
                                                 Id = i,
                                                 AlternateText = "AlternateText " + i,
                                                 Description = "Description " + i,
                                                 Name = "Name " + i,
                                             });
                }
                for (var i = 20; i < 30; i++)
                {
                    _imageViewModels.Add(new ImageViewModel
                                             {
                                                 Id = i,
                                                 AlternateText = "AlternateText " + i,
                                                 Description = "Description " + i,
                                                 Name = "Name " + i,
                                             });
                }

            }

            public int GetCount()
            {
                return _imageViewModels.Count;
            }

            public IEnumerable<ImageViewModel> FindRange(string format, int i, int recordsCount)
            {
                return _imageViewModels.Skip(i).Take(recordsCount);
            }

            public void Add(Image image)
            {
            }

            public IEnumerable<Image> GetImages()
            {
                var images = new List<Image>();
                foreach (var imageViewModel in _imageViewModels)
                {
                    images.Add(new Image(imageViewModel));
                }
                return images;
            }

            #region Implementation of IDisposable

            public void Dispose()
            {
                _context.Dispose();
            }

            #endregion

 }
}
6rqinv9w

6rqinv9w1#

使用Moq,您将不需要手动创建模拟对象,这本身就可以保存您的时间。
您将设置Moq来告诉它如何根据调用的内容/方式来执行操作,而不是手动创建这些模拟对象。
使用此方法,您将能够执行以下操作:

  • 根据不同的输入设置不同的响应,或提供相同的结果而不考虑输入(使用设置)
  • 允许您通过提交参数的捕获所有值(使用It.IsAny〈〉或It.Is〈〉)来简化测试代码
  • 验证方法已被调用的次数,或者是否已被调用。(使用验证)。这将允许您测试是否已使用正确的参数调用了特定的相关性定义的次数。
  • 设置或验证代码将引发特定异常(使用Throws)

当您掌握了Moq,对于中等复杂度的测试用例,您将看到编写测试用例的收获。
当然,您可以手动完成所有这些工作,但是在模拟中编写这些工具将非常耗时。

k10s72fa

k10s72fa2#

在某些情况下,您的方法可能是最简单的。但是,当您模拟的对象的行为比较复杂或变化较大时,您通常会遇到以下两种情况之一:

  • 功能略有不同的模拟类的激增。
  • 一个mock类,带有各种控件来调整mock行为,这很容易引入bug。

使用像Moq这样的模拟库可以让您非常清楚地定义您的行为,通常与您的测试“内联”,因此交互更加清晰和直接。

f0ofjuux

f0ofjuux3#

Moq可以让你跳过你已经创建的存储库,但是Mock对象的主要用途是隔离你的单元测试。
例如:如果你想测试一个对象对一些数据的React,你可以模拟这些数据。
在您的情况下,可以执行以下操作:

// Create the mock from your interface
var mock = new Mock<IImagesRepository>();

// Setup the mock so it will return what you want
mock.Setup(foo => foo.GetImages()).Returns(new ImageViewModel
                                         {
                                             Id = i,
                                             AlternateText = "AlternateText " + i,
                                             Description = "Description " + i,
                                             Name = "Name " + i,
                                         });

// Then you can use it
functionThatNeedAnImageViewModel(mock.Object.GetImages());

看看这个Moq QuickStart了解更多信息。

vwkv1x7d

vwkv1x7d4#

你最终会维护两个存储库,一真实的,一个虚假的。更糟糕的是,你的虚假存储库不能真正伪造一切,例如,两个对象之间的关系,除非你做了大量的编码。最终,如果你有比你的例子更复杂的对象,这将是不值得的。
不仅如此,当测试一个依赖于存储库的类时,存储库不是测试的重点,因此使用MOQ或RhinoMock这样的框架进行模拟要容易得多。

相关问题