我在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或重构它以使其更易测试?谢谢。
答案 0 :(得分:0)
几点:
GetProfileImage
内的图片时,您应该测试这些更新是否正确完成。这是你将编写单元测试的情况之一。 希望这有帮助。
答案 1 :(得分:0)
我花了太长时间,但这对我来说是一次非常好的学习经历。我是这样做的:
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);
}
呼!很多工作,但同样,对我来说是一个很好的学习经历,如果我再次需要这个代码,我就拥有它。我也希望这对有这种担忧的其他人有用。