【问题标题】:How to unit test controller with WebImage in ASP. Net MVC App如何在 ASP 中使用 WebImage 对控制器进行单元测试。网络 MVC 应用程序
【发布时间】:2014-07-30 01:07:23
【问题描述】:

我在 MVC 控制器中有这个非常简单的方法:

    public void GetProfileImage(int id)
    {
        var data = _companyService.GetProfileImage(id);

        if (data == null)
            return;

        var image = new WebImage(data).ResizeMaxPreserveTransparency(250, 250);
        image.Write();
    }

是否有人对我如何测试、模拟 WebImage 或重构它以使其更可测试有任何建议?谢谢。

【问题讨论】:

  • 澄清一下,companyService 返回 null 的场景显然是一个非常容易模拟和测试的场景。 WebImage 让我感到悲伤。

标签: c# asp.net-mvc unit-testing moq


【解决方案1】:

几点:

  1. 方法名称以“Get”开头,方法不返回任何内容。
  2. 当您更新GetProfileImage 中的图像时,您应该测试这些更新是否正确完成。这是您将编写单元测试的情况之一。
  3. 为了测试方法行为(例如,图像最大透明度设置为 250),您应该返回图像对象。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我在这方面花了太长时间,但这对我来说是一次非常好的学习经历。我是这样做的:

    1) 创建一个封装了我需要的WebImage的方法和属性的接口:

     public interface IWebImage
     { 
        void Write(string requestedFormat = null);
    
        string ImageFormat { get; }
    
        int Width { get; }
    
        int Height { get; }
    
        byte[] GetBytes(string requestedFormat = null);
    
        IWebImage Resize(int width, int height, bool preserveAspectRatio = true, bool preventEnlarge = false);
    }
    

    2) 创建一个实现此接口的包装器,它是实际 WebImage 的包装器:

     public class WebImageWrapper : IWebImage
     {
        private readonly WebImage _instance;
    
        public WebImageWrapper(byte[] data)
        {
            _instance = new WebImage(data);
        }
    
        public WebImageWrapper(WebImage image)
        {
            _instance = image;
        }
    
        public void Write(string requestedFormat = null)
        {
            _instance.Write(requestedFormat);
        }
    
        public string ImageFormat { get { return _instance.ImageFormat; } }
    
        public int Width { get { return _instance.Width; } }
    
        public int Height { get { return _instance.Height; } }
    
        public byte[] GetBytes(string requestedFormat = null)
        {
            return _instance.GetBytes(requestedFormat);
        }
    
        public IWebImage Resize(int width, int height, bool preserveAspectRatio = true, bool preventEnlarge = false)
        {
            return new WebImageWrapper(_instance.Resize(width, height, preserveAspectRatio, preventEnlarge));
        }
    }
    

    3) 为工厂创建一个接口,该接口可以被模拟以提供模拟的 IWebImage,也可以被注入以提供实际的 WebImageWrapper。

    public interface IWebImageFactory
    {
        IWebImage Get(byte[] data);
    }
    

    4) 这个工厂接口的真正实现,将由 Ninject 注入到控制器中,如下所示:

    public class WebImageFactory : IWebImageFactory
    {
        public IWebImage Get(byte[] data)
        {
            return new WebImageWrapper(data);
        }
    }
    

    5) 最后,我的控制器方法现在看起来像这样:

        public void GetProfileImage(int? id)
        {
            var data = _companyService.GetProfileImage(id);
    
            if (data == null)
                return;
    
            var image = WebImageFactory.Get(data).ResizeMaxPreserveTransparency(250, 250);
            image.Write();
        }
    

    6) WebImageFactory 是一个注入属性,所以我可以提供任何我想要的模拟,而这反过来又可以提供一个模拟的 IWebImage。从这一点开始,创建单元测试就变得微不足道了。

        [TestMethod]
        public void GetProfileImageTest()
        {
            // Arrange
            var byteArray = new[] {(byte) 12, (byte) 13};
            var image = new Mock<IWebImage>();
            var factory = new Mock<IWebImageFactory>();
            var companyService = new Mock<ICompanyService>();
    
            companyService.Setup(c => c.GetProfileImage(99)).Returns(byteArray);
            factory.Setup(f => f.Get(byteArray)).Returns(image.Object);
            var target = new CompanyProfileController(Mock.Of<ICompanyProfileService>(), companyService.Object)
            {
                WebImageFactory = factory.Object
            };
    
            // Act
            target.GetProfileImage(99);
    
            // Assert
            image.Verify(i => i.Write(null), Times.Once);
        }
    

    哇!很多工作,但同样,对我来说,这是一次很好的学习经历,如果我再次需要这段代码,我就有了。我也希望它对有这个问题的其他人有用。

    【讨论】:

      猜你喜欢
      • 2020-10-13
      • 2014-05-27
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 2014-02-08
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      相关资源
      最近更新 更多