3

我遇到了一些关于使用 Moq 进行单元测试的参考资料。但是在查看 moq 的 wiki 示例后,我真的看不出比创建模拟存储库有什么好处。我错过了什么吗。下面是我创建的模拟存储库的示例。起订量可以以任何方式优化吗?

    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


 }
}
4

4 回答 4

4

使用 Moq,您无需手动创建模拟对象。仅此一项就可以节省您的时间。

无需手动创建这些模拟对象,您将设置 Moq 以根据调用的内容/方式告诉它如何表现。

使用此方法,您将能够执行以下操作:

  • 根据不同的输入设置各种响应或提供相同的结果而不考虑输入(使用设置)

  • 允许您通过提交捕获所有参数值来简化测试代码(使用 It.IsAny<> 或 It.Is<>)

  • 验证一个方法被调用的次数,或者它是否被调用过。(使用验证)。这将允许您测试某些依赖项是否已使用正确的参数调用了定义的次数。

  • 设置或验证代码是否会抛出某个异常(使用 Throws)

当您掌握起订量时,对于中等复杂的测试用例,您将看到编写测试用例的好处。

当然,您可以手动完成所有这些事情,但是在您的模拟中编写这些设施将非常耗时。

于 2012-06-26T15:43:39.797 回答
3

对于某些情况,您的方法可能是最简单的。但是,当您要模拟的对象的行为更复杂或更多样化时,您通常会得到以下结果:

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

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

于 2012-06-26T15:36:22.047 回答
0

Moq 将使您能够跳过您创建的存储库。但是 Mock 对象的主要用途是隔离您的单元测试。

示例:如果您想测试对象如何对某些数据做出反应。您可以模拟该数据。

在您的情况下,您可以执行以下操作:

// 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快速入门了解更多信息。

于 2012-06-26T15:34:43.480 回答
0

您最终将维护两个存储库,一个是真实的,一个是假的。更糟糕的是,除非您进行大量编码,否则您的伪造者无法真正伪造所有内容,例如两个对象之间的关系。最终,如果你有比你的例子更复杂的对象,那将是不值得的。

更重要的是,当测试一个依赖于您的存储库的类时,存储库不是测试的重点,因此使用 MOQ 或 RhinoMock 等框架进行模拟要容易得多。

于 2012-06-26T15:41:24.010 回答