使用Moq之类的好处

时间:2012-06-26 15:20:26

标签: .net unit-testing repository moq

我遇到了一些使用Moq进行单元测试的参考资料。但在查看moq的wiki示例之后,我无法真正看到创建模拟存储库的任何好处。我错过了一些事情。下面是我创建的模拟存储库的示例。 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


 }
}

4 个答案:

答案 0 :(得分:4)

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

而不是手动创建这些模拟对象,您将设置Moq以告诉它如何根据事件的调用方式进行操作。

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

  • 根据不同的输入设置各种响应或提供相同的结果,无论输入如何(使用设置)

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

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

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

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

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

答案 1 :(得分:3)

对于某些情况,您的方法可能最简单。但是,当您正在模拟的对象的行为更复杂或变化时,通常最终会得到:

  • 功能略有不同的模拟类的扩散。
  • 一个带有各种控件的模拟类,用于调整模拟行为,这很容易引入错误。

使用像Moq这样的模拟库可以让你非常清楚地定义你的行为,通常用你的测试内联,这样互动就会更清晰,更直接。

答案 2 :(得分: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 QuickStart获取更多信息。

答案 3 :(得分:0)

你最终会维护两个存储库,一个是真实的,一个是假的。更糟糕的是,你的伪造的东西不能真正伪造一切,例如,两个对象之间的关系,除非你做了很多编码。最终,如果你的对象比你的例子更复杂,那将是不值得的。

不仅如此,在测试依赖于存储库的类时,存储库不是测试的重点,因此使用MOQ或RhinoMock等框架进行模拟更容易。