应用程序 MVC Moq 中的最小起订量 File.Delete (IFileSystem)
How moq File.Delete (IFileSystem) in app MVC Moq
我的方法有效
[HttpPost]
public async Task<ActionResult> DeleteTeam(int id)
{
Team team = await teamRepository.DeleteTeamAsync(id);
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), team.Path);
if (System.IO.File.Exists(fileToDeletePath))
{
System.IO.File.Delete(fileToDeletePath);
}
if (team != null)
{
TempData["message"] = string.Format("{0} был удален", team.Name);
}
return RedirectToAction("Index", "Player");
}
我尝试做一个测试,但是没有成功
[TestMethod]
public async Task CanDeletePlayerAsync()
{
//Arrange
Mock<ITeamRepository> teamsMock = new Mock<ITeamRepository>();
Team team2 = new Team { Id = 2, Name = "Boston" , Path = "CHi.png" };
Team team3 = new Team { Id = 3, Name = "Lakers" };
string fullPath = ("~/Images/NBAlogoImg/");
var serverMock = new Mock<HttpServerUtilityBase>();
serverMock.Setup(x => x.MapPath(fullPath)).Returns(@"s:\work");
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(x => x.Server).Returns(serverMock.Object);
var mockFile = new Mock<IFileSystem>();
TeamController controller = new TeamController(teamsMock.Object);
controller.ControllerContext = new ControllerContext(httpContextMock.Object, new RouteData(), controller);
teamsMock.Setup(m => m.DeleteTeamAsync(team2.Id)).Returns(Task.FromResult(team2));
// Act
ActionResult result = await controller.DeleteTeam(team2.Id);
mockFile.Verify(x => x.File.Delete(@"s:\work\file.png"));
//Assert
Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
}
如果我删除团队,我添加了从应用程序中删除图像的功能。完美无缺,但是如何通过最小起订量进行测试我尝试了一些未成功。
我有错误信息
Expected invocation on the mock at least once, but was never performed: x => x.File.Delete("s:\work\file.png")
No setups configured.
No invocations performed.
怎么解决的?我已经下载 IFileSystem
并制作了最小起订量,但验证无效。
一个明显的解决方案是将您的 File.Delete 调用包装在自定义 Class 中,它实现了一个自定义接口,例如,
public interface IFileOperations
{
void Delete(string path);
}
对于您的系统操作,您可以创建一个包装器 class。
public class SystemFileOperations:IFileOperations
{
public void Delete(string path)
{
File.Delete(path);
}
}
现在您可以更改原始代码以确保在所有需要的地方注入 SystemFileOperations IFileOperations.Delete。
private IFileOperations _fileOperations;
public ControllerName(IFileOperations operations)
{
_fileOperations = operations;
}
随后将替换下一行
System.IO.File.Delete(fileToDeletePath);
和
_fileOperations.Delete(fileToDeletePath);
对于模拟,你可以
var mock = new Mock<IFileOperations>();
mock.Verify(x=>x.Delete(path),Times.AtLeastOnce());
请注意,在您的情况下,由于 File.Exists 的使用,如果您愿意,您可能还必须模拟它并遵循相同的模式
我的方法有效
[HttpPost]
public async Task<ActionResult> DeleteTeam(int id)
{
Team team = await teamRepository.DeleteTeamAsync(id);
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), team.Path);
if (System.IO.File.Exists(fileToDeletePath))
{
System.IO.File.Delete(fileToDeletePath);
}
if (team != null)
{
TempData["message"] = string.Format("{0} был удален", team.Name);
}
return RedirectToAction("Index", "Player");
}
我尝试做一个测试,但是没有成功
[TestMethod]
public async Task CanDeletePlayerAsync()
{
//Arrange
Mock<ITeamRepository> teamsMock = new Mock<ITeamRepository>();
Team team2 = new Team { Id = 2, Name = "Boston" , Path = "CHi.png" };
Team team3 = new Team { Id = 3, Name = "Lakers" };
string fullPath = ("~/Images/NBAlogoImg/");
var serverMock = new Mock<HttpServerUtilityBase>();
serverMock.Setup(x => x.MapPath(fullPath)).Returns(@"s:\work");
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(x => x.Server).Returns(serverMock.Object);
var mockFile = new Mock<IFileSystem>();
TeamController controller = new TeamController(teamsMock.Object);
controller.ControllerContext = new ControllerContext(httpContextMock.Object, new RouteData(), controller);
teamsMock.Setup(m => m.DeleteTeamAsync(team2.Id)).Returns(Task.FromResult(team2));
// Act
ActionResult result = await controller.DeleteTeam(team2.Id);
mockFile.Verify(x => x.File.Delete(@"s:\work\file.png"));
//Assert
Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
}
如果我删除团队,我添加了从应用程序中删除图像的功能。完美无缺,但是如何通过最小起订量进行测试我尝试了一些未成功。
我有错误信息
Expected invocation on the mock at least once, but was never performed: x => x.File.Delete("s:\work\file.png") No setups configured. No invocations performed.
怎么解决的?我已经下载 IFileSystem
并制作了最小起订量,但验证无效。
一个明显的解决方案是将您的 File.Delete 调用包装在自定义 Class 中,它实现了一个自定义接口,例如,
public interface IFileOperations
{
void Delete(string path);
}
对于您的系统操作,您可以创建一个包装器 class。
public class SystemFileOperations:IFileOperations
{
public void Delete(string path)
{
File.Delete(path);
}
}
现在您可以更改原始代码以确保在所有需要的地方注入 SystemFileOperations IFileOperations.Delete。
private IFileOperations _fileOperations;
public ControllerName(IFileOperations operations)
{
_fileOperations = operations;
}
随后将替换下一行
System.IO.File.Delete(fileToDeletePath);
和
_fileOperations.Delete(fileToDeletePath);
对于模拟,你可以
var mock = new Mock<IFileOperations>();
mock.Verify(x=>x.Delete(path),Times.AtLeastOnce());
请注意,在您的情况下,由于 File.Exists 的使用,如果您愿意,您可能还必须模拟它并遵循相同的模式