Asp.net mvc 单元测试文件上载失败

Asp.net mvc 单元测试文件上载失败,asp.net-mvc,unit-testing,Asp.net Mvc,Unit Testing,我有一个在数据库中插入文件的操作。它很好用。但当插入成功时,单元测试失败。RedirectToRouteResult为空。这是操作的代码: [HttpPost] 公共操作结果文件上载(文件上载视图模型) { 尝试 { if(ModelState.IsValid) { var uploadFile=新字节[model.File.InputStream.Length]; model.File.InputStream.Read(uploadFile,0,uploadFile.Length); //va

我有一个在数据库中插入文件的操作。它很好用。但当插入成功时,单元测试失败。RedirectToRouteResult为空。这是操作的代码:

[HttpPost]
公共操作结果文件上载(文件上载视图模型)
{
尝试
{
if(ModelState.IsValid)
{
var uploadFile=新字节[model.File.InputStream.Length];
model.File.InputStream.Read(uploadFile,0,uploadFile.Length);
//var file=新文件上传();
var fileExt=Path.GetExtension(model.File.FileName);
如果(fileExt==“.txt”| | fileExt==“.docx”)
{
//file.FileName=model.file.FileName;
//file.FileSize=model.file.ContentLength;
//file.ContentType=fileExt;
//file.FileData=上传文件;
//file.UploadedOn=DateTime.Now;
//var user=\u userRepository.GetUserId(user.Identity.Name);
//file.UserId=user.UserId;
bool result=\u userRepository.UploadFile(model,User.Identity.Name,fileExt,UploadFile);
//file.User=(从u.UserId==29的_context.Users中的u中选择u);
//_context.FilesUploads.Add(文件);
//int result=_context.SaveChanges();
如果(结果)
{
返回操作(“索引”);
}
其他的
{
AddModelError(“,“发生错误”);
返回视图(模型);
}
}
其他的
{
ModelState.AddModelError(“,”您只能上载扩展名为.txt和.docx的文件”);
}
}
返回视图(模型);
}
捕获(例外情况除外)
{
投掷(ex);
} 
}

这是单元测试的代码:

    private SuperUserController _controller;
    private Mock<IUserRepository> _repositoryMock;
    private Mock<IIntrinsicObjects> _intrinsicMock;
    private Mock<ControllerContext> _contextMock;
    private string username = "test@abv.bg";
    private FileUploadViewModel _fileUpload;

    [SetUp]
    public void Setup()
    {
        _fileUpload = new FileUploadViewModel();
        _repositoryMock = new Mock<IUserRepository>();
        _intrinsicMock = new Mock<IIntrinsicObjects>();
        _contextMock = new Mock<ControllerContext>();
        _contextMock.SetupGet(c => c.HttpContext.User.Identity.Name).Returns(username);
        _contextMock.SetupGet(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true);
        _controller = new SuperUserController(_repositoryMock.Object, _intrinsicMock.Object);
        _controller.ControllerContext = _contextMock.Object;
    }


[Test]
    public void FileUpload_ShouldRedirectToIndexOnSuccess()
    {
        string filePath = Path.GetFullPath(@"C:\Users\Test\Desktop\test.txt");
        var fileStream = new FileStream(filePath, FileMode.Open);
        var fileExt = Path.GetExtension(filePath);
        var fileToUpload = new Mock<HttpPostedFileBase>();
        fileToUpload.Setup(f => f.ContentLength).Returns(10);
        fileToUpload.Setup(f => f.FileName).Returns("test.txt");
        fileToUpload.Setup(f => f.ContentType).Returns(fileExt);
        fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
        //var model = new FileUploadViewModel();
        _fileUpload.File = fileToUpload.Object;
        var fileData = new byte[fileToUpload.Object.InputStream.Length];
        _repositoryMock.Setup(m => m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name, fileToUpload.Object.ContentType, fileData)).Returns(true);
        var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
        Assert.IsNotNull(result);
    }
public void FileUpload_ShouldRedirectToIndexOnSuccess()
{
    var fileData = UTF8Encoding.UTF8.GetBytes("This is a test");
    var fileStream = new MemoryStream(fileData);

    var fileToUpload = new Mock<HttpPostedFileBase>();
    fileToUpload.Setup(f => f.ContentLength).Returns((int)fileStream.Length);
    fileToUpload.Setup(f => f.FileName).Returns("test.txt");
    fileToUpload.Setup(f => f.ContentType).Returns("txt");
    fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
    _fileUpload.File = fileToUpload.Object;            

    _repositoryMock
        .Setup(m => m.UploadFile(_fileUpload, username, ".txt", MatchCollection(fileData)))
        .Returns(true);

    var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
    Assert.IsNotNull(result);
}
private SuperUserController\u控制器;
私人模拟(repositoryMock),;
私有Mock_intrinsicMock;
私有Mock_contextMock;
私有字符串用户名=”test@abv.bg";
private FileUploadViewModel\u fileUpload;
[设置]
公共作废设置()
{
_fileUpload=新建FileUploadViewModel();
_repositoryMock=新建Mock();
_intrinsicMock=newmock();
_contextMock=newmock();
_SetupGet(c=>c.HttpContext.User.Identity.Name).Returns(用户名);
_SetupGet(c=>c.HttpContext.User.Identity.IsAuthenticated)。返回(true);
_控制器=新的超级用户控制器(_repositoryMock.Object,_intrinsicMock.Object);
_controller.ControllerContext=\u contextMock.Object;
}
[测试]
公共无效文件上载\u应重定向到IndexonSuccess()
{
字符串filePath=Path.GetFullPath(@“C:\Users\Test\Desktop\Test.txt”);
var fileStream=newfilestream(filePath,FileMode.Open);
var fileExt=Path.GetExtension(filePath);
var fileToUpload=new Mock();
Setup(f=>f.ContentLength).Returns(10);
Setup(f=>f.FileName)。返回(“test.txt”);
Setup(f=>f.ContentType).Returns(fileExt);
Setup(f=>f.InputStream)。返回(fileStream);
//var model=new FileUploadViewModel();
_fileUpload.File=fileToUpload.Object;
var fileData=新字节[fileToUpload.Object.InputStream.Length];
_repositoryMock.Setup(m=>m.UploadFile(_fileUpload,_controller.ControllerContext.HttpContext.User.Identity.Name,fileToUpload.Object.ContentType,fileData))。返回(true);
var result=_controller.FileUpload(_FileUpload)作为RedirectToRouteResult;
Assert.IsNotNull(结果);
}
问题是UploadFile总是返回false


如果有人帮助我,我将非常感激。

您的控制器操作将使用文件数据创建一个新数组:

var uploadFile = new byte[model.File.InputStream.Length];
这永远不会与
\u repositoryMock
UploadFile
上设置的
fileData
参数匹配:

_repositoryMock.Setup(m => m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name, fileToUpload.Object.ContentType, fileData)).Returns(true);
默认情况下,数组将通过引用匹配,而不是在内容相同时匹配。当控制器创建新实例时,
uploadFile
是与
fileData
不同的引用

您希望设置moq,以便在提交预期的数据数组时,UploadFile函数返回true。为此,您可以使用自定义匹配器来匹配可枚举中的所有元素:

public T[] MatchCollection<T>(T[] expectation)
{
    //This checks all elements in input are find in destination, regardless of order or duplicates
    return Match.Create<T[]>(inputCollection => (expectation.All((i) => inputCollection.Contains(i))));

    //This will check the arrays are exactly the same
    return Match.Create<T[]>(inputCollection =>  StructuralComparisons.StructuralEqualityComparer.Equals(inputCollection, expectation) );
}
希望有帮助

编辑


我根据您的代码尝试了以下测试,该测试将有效的数组数据传递给模拟设置,并且不需要在单元测试中实际读取文件:

    private SuperUserController _controller;
    private Mock<IUserRepository> _repositoryMock;
    private Mock<IIntrinsicObjects> _intrinsicMock;
    private Mock<ControllerContext> _contextMock;
    private string username = "test@abv.bg";
    private FileUploadViewModel _fileUpload;

    [SetUp]
    public void Setup()
    {
        _fileUpload = new FileUploadViewModel();
        _repositoryMock = new Mock<IUserRepository>();
        _intrinsicMock = new Mock<IIntrinsicObjects>();
        _contextMock = new Mock<ControllerContext>();
        _contextMock.SetupGet(c => c.HttpContext.User.Identity.Name).Returns(username);
        _contextMock.SetupGet(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true);
        _controller = new SuperUserController(_repositoryMock.Object, _intrinsicMock.Object);
        _controller.ControllerContext = _contextMock.Object;
    }


[Test]
    public void FileUpload_ShouldRedirectToIndexOnSuccess()
    {
        string filePath = Path.GetFullPath(@"C:\Users\Test\Desktop\test.txt");
        var fileStream = new FileStream(filePath, FileMode.Open);
        var fileExt = Path.GetExtension(filePath);
        var fileToUpload = new Mock<HttpPostedFileBase>();
        fileToUpload.Setup(f => f.ContentLength).Returns(10);
        fileToUpload.Setup(f => f.FileName).Returns("test.txt");
        fileToUpload.Setup(f => f.ContentType).Returns(fileExt);
        fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
        //var model = new FileUploadViewModel();
        _fileUpload.File = fileToUpload.Object;
        var fileData = new byte[fileToUpload.Object.InputStream.Length];
        _repositoryMock.Setup(m => m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name, fileToUpload.Object.ContentType, fileData)).Returns(true);
        var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
        Assert.IsNotNull(result);
    }
public void FileUpload_ShouldRedirectToIndexOnSuccess()
{
    var fileData = UTF8Encoding.UTF8.GetBytes("This is a test");
    var fileStream = new MemoryStream(fileData);

    var fileToUpload = new Mock<HttpPostedFileBase>();
    fileToUpload.Setup(f => f.ContentLength).Returns((int)fileStream.Length);
    fileToUpload.Setup(f => f.FileName).Returns("test.txt");
    fileToUpload.Setup(f => f.ContentType).Returns("txt");
    fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
    _fileUpload.File = fileToUpload.Object;            

    _repositoryMock
        .Setup(m => m.UploadFile(_fileUpload, username, ".txt", MatchCollection(fileData)))
        .Returns(true);

    var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
    Assert.IsNotNull(result);
}
public void FileUpload\u应该重定向到indexonsuccess()
{
var fileData=UTF8Encoding.UTF8.GetBytes(“这是一个测试”);
var fileStream=新内存流(fileData);
var fileToUpload=new Mock();
Setup(f=>f.ContentLength)。返回((int)fileStream.Length);
Setup(f=>f.FileName)。返回(“test.txt”);
Setup(f=>f.ContentType).Returns(“txt”);
Setup(f=>f.InputStream)。返回(fileStream);
_fileUpload.File=fileToUpload.Object;
_重置模拟
.Setup(m=>m.UploadFile(_fileUpload,username,“.txt”,MatchCollection(fileData)))
.返回(真);
var result=_controller.FileUpload(_FileUpload)作为RedirectToRouteResult;
Assert.IsNotNull(结果);
}

这是测试的最终版本:

[Test]
    public void FileUpload_ShouldRedirectToIndexOnSuccess()
    {
        string filePath = Path.GetFullPath(@"C:\Users\Yordanka\Desktop\test.txt");
        var fileStream = new FileStream(filePath, FileMode.Open);
        var fileExt = Path.GetExtension(filePath);
        var testarray = new byte[414];
        var fileToUpload = new Mock<HttpPostedFileBase>();
        fileToUpload.Setup(f => f.ContentLength).Returns(414);
        fileToUpload.Setup(f => f.FileName).Returns("test.txt");
        fileToUpload.Setup(f => f.ContentType).Returns(fileExt);
        fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
        fileToUpload.Setup(f => f.InputStream.Length).Returns(testarray.Length);
        _fileUpload.File = fileToUpload.Object;
        var fileData = new byte[414];
        _fileUpload.File.InputStream.Read(fileData, 0, fileData.Length);
        _repositoryMock.Setup(
            m =>
                m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name,
                    fileToUpload.Object.ContentType, MatchCollection(fileData))).Returns(true);
        var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
        Assert.IsNotNull(result);
        Assert.AreEqual("Index", result.RouteValues["Action"]);
        Assert.AreEqual("SuperUser", result.RouteValues["Controller"]);

    }
[测试]
普布利