【发布时间】:2013-12-08 06:47:01
【问题描述】:
我正在尝试找出为 MVC 应用程序构建单元测试的最佳方法。我创建了一个简单的模型和接口,供控制器构造函数使用,以便测试框架 (Nsubstitute) 可以传递存储库的模拟版本。该测试按预期通过。
我的问题是现在我想更进一步,在 IHomeRepository 的“真实”实例中测试文件 I/O 操作。此实现应该从 App_Data 目录中的文件中读取一个值。
我尝试在不传递 IHomeRepsotory 的模拟版本的情况下构建测试,但是当我运行测试时 HttpContext.Current 为空。
我需要模拟 HttpContext 吗?我是否以正确的方式处理这件事?
//The model
public class VersionModel
{
public String BuildNumber { get; set; }
}
//Interface defining the repository
public interface IHomeRepository
{
VersionModel Version { get; }
}
//define the controller so the unit testing framework can pass in a mocked reposiotry. The default constructor creates a real repository
public class HomeController : Controller
{
public IHomeRepository HomeRepository;
public HomeController()
{
HomeRepository = new HomeRepoRepository();
}
public HomeController(IHomeRepository homeRepository)
{
HomeRepository = homeRepository;
}
.
.
.
}
class HomeRepoRepository : IHomeRepository
{
private VersionModel _version;
VersionModel IHomeRepository.Version
{
get
{
if (_version == null)
{
var absoluteFileLocation = HttpContext.Current.Server.MapPath("~/App_Data/repo.txt");
if (absoluteFileLocation != null)
{
_version = new VersionModel() //read the values from file (not shown here)
{
BuildNumber = "value from file",
};
}
else
{
throw new Exception("path is null");
}
}
return _version;
}
}
}
[Fact]
public void Version()
{
// Arrange
var repo = Substitute.For<IHomeRepository>(); //using Nsubstitute, but could be any mock framework
repo.Version.Returns(new VersionModel
{
BuildNumber = "1.2.3.4",
});
HomeController controller = new HomeController(repo); //pass in the mocked repository
// Act
ViewResult result = controller.Version() as ViewResult;
var m = (VersionModel)result.Model;
// Assert
Assert.True(!string.IsNullOrEmpty(m.Changeset));
}
【问题讨论】:
标签: asp.net-mvc unit-testing mocking