How to mock test with asp.net mvc - asp.net-mvc

I am writing an app that I have been deploying to appharbor. I am having trouble getting my project to build now because I have expanded my tests. I believe the issue is that I am using a db initializer to populate the database with test seed data. These tests pass on my local box but once I deploy the tests fail on appharbor. I suspect I need to mock data but I am not sure how to do this. As an example, here is a controller test that I have for one of my action methods.
Controller
// GET: /Lead/Url
// TODO: Add optional url parameters
public ActionResult Url(string pfirstname, string plastname, string phone, int leadsource)
{
var lead = new Lead();
//store
lead.parent_FirstName = pfirstname;
lead.parent_LastName = plastname;
lead.parent_Phone = phone;
lead.LeadSourceID = leadsource;
lead.AgentID = 1;
if (ModelState.IsValid)
{
leadRepository.InsertLead(lead);
leadRepository.Save();
ViewBag.Message = "Success";
}
return View(lead);
}
//
// POST: /Lead/URL
[HttpPost, ActionName("Url")]
public ActionResult Url(Lead lead)
{
return View();
}
Unit Test
[TestMethod]
public void LeadUrl()
{
//ARRANGE
ILeadRepository leadrepository = new LeadRepository(new LeadManagerContext());
Database.SetInitializer<LeadManagerContext>(new LeadManagerInitializer());
LeadController controller = new LeadController(leadrepository);
//ACT
ViewResult result = controller.Url("Brad", "woods","465-456-4965",1) as ViewResult;
var lead = (Lead)result.ViewData.Model;
//ASSERT
Assert.AreEqual("Success" ,result.ViewBag.Message);
/*check for valid data */
Assert.AreEqual("Brad", lead.parent_FirstName);
}
Could someone please explain what I need to do next in order to improve code like this and get it to run again on app harbor successfully?

Actually you haven't verified interactions between controller and it's dependencies (repository). And this is the most important part - controller should pass your Lead object to repository. And then call Save (consider also to Unit Of Work pattern).
Also you should test controller in isolation, only this way you could be sure, that failing controller's test is an issue of controller, not of LeadRepository or LeadManagerInitializer.
// Arrange
Lead expected = CreateBrad();
var repository = new Mock<ILeadRepository>();
LeadController controller = new LeadController(repository.Object);
// Act
ViewResult result = (ViewResult)controller.Url("Brad", "woods", "465-456", 1);
// Assert
Lead actual = (Lead)result.ViewData.Model;
// All fields should be equal, not only name
Assert.That(actual, Is.EqualTo(expected));
Assert.AreEqual("Success", result.ViewBag.Message);
// You need to be sure, that expected lead object passed to repository
repository.Verify(r => r.InsertLead(expected));
repository.Verify(r => r.Save());
BTW I'd moved expected Lead creation to separate method:
private Lead CreateBrad()
{
Lead lead = new Lead();
lead.parent_FirstName = "Brad";
lead.parent_LastName = "woods";
lead.parent_Phone = "465-456";
lead.LeadSourceID = 1;
lead.AgentID = 1;
return lead;
}
Also you should override Equals method for Lead instances comparison:
public class Lead
{
// your current code here
public override bool Equals(object obj)
{
Lead other = obj as Lead;
if (other == null)
return false;
return other.parent_FirstName == parent_FirstName &&
other.parent_LastName == parent_LastName &&
// compare other properties here
other.AgentID == AgentID;
}
// also override GetHashCode method
}
BTW Why you don't pass Lead object to your action method (via POST message)?

You have to stub your repository. The easiest way to do that is to use mocking framework (I prefer Moq), and stub each method.
Something like this (for Moq):
var repository = new Mock<ILeadReporisory>();
repository.Setup(r => r.InsertLead(It.IsAny<Lead>()));
//raise, rinse, repeat
LeadController controller = new LeadController(repository.Object);

Related

How to pass Model value from Test class to Action Method in Controller class

I am creating some Nunit tests for an MVC application. I am writing a test case for a methods in my Controller class. I am using Nsubstitute for Mocking the object.
I am learning about Nunit and Nsubstitue and I don't know, how to pass my Model value which was mocked in the testcase method to my controller method.
Below is my method in the controller class:
public ActionResult Manage(string id)
{
var clusterCollections = ReadXml();
int clusterIndex = clusterCollections.ClusterCollectionList.FindIndex(a => a.ClusterId == id);
var model = new ClusterManagementModel()
{
ClusterNodeDetailsList = BindClusterDetailsToGrid(id),
DropDownListClusterName = BindClusterNameToDropDown(),
CurrentClusterId = clusterIndex,
CurrentClusterName = id,
HStatus = Hstatus(id),
IStatus = Istatus(id)
};
return View(model);
}
This is the TestCase I have written:
[TestCase]
public void TestManage()
{
var ManagementController = Substitute.ForPartsOf<ClusterManagementController>();
var ManagementModel = Substitute.ForPartsOf<ClusterManagementModel>();
ClusterCollections clusterCollection = new ClusterCollections();
List<ClusterNodeDetails> ClusterNodes = new List<ClusterNodeDetails>();
List<DDL_ClusterName> DropDownListClusterName = new List<DDL_ClusterName>();
ManagementController.ReadXml().Returns(clusterCollection);
ManagementModel = new ClusterManagementModel()
{
ClusterNodeDetailsList = ClusterNodes,
DropDownListClusterName = DropDownListClusterName,
CurrentClusterId = 1,
CurrentClusterName = "UnitTesting",
HStatus = "True",
IStatus = "Success"
};
var result = ManagementController.Manage("1") as ActionResult;
Assert.AreEqual(ManagementModel, result);
}
If I have made mistakes in the TestCase Method please correct me.
If my TestCase is wrong, can you give me a suggestion how to write a TestCase for the above method (public ActionResult Manage(string id))
I don't know, how to pass Model value
The short answer is that in its current form, you can't pass the model you've created in your test to your controller. This is a common problem that people run into when they first start trying to unit test their code. The way out of the hole is to start writing your production code with testing in mind.
One approach that is common is to extract dependencies from your class and to inject these dependencies through the constructor for the class. So, you might extract your model creation logic into a ModelFactory and modify your controller to have a constructor like this:
public ManagementController(IModelFactory modelFactory) {
_modelFactory = modelFactory;
}
There are various libraries that can help to inject these dependencies (Ninject, AutoFac etc). But if you don't want to / can't use them, then you will also need to add a default constructor that sets up your dependencies to default concrete implementations:
public ManagementController() {
_modelFactory = new ModelFactory();
}
This allows you to create Stubbed / Mocked / Substituted implementations of IModelFactory and inject it into your controller / other class under test. So, your test might start off something like this:
List<ClusterNodeDetails> ClusterNodes = new List<ClusterNodeDetails>();
List<DDL_ClusterName> DropDownListClusterName = new List<DDL_ClusterName>();
var model = new ClusterManagementModel()
{
ClusterNodeDetailsList = ClusterNodes,
DropDownListClusterName = DropDownListClusterName,
CurrentClusterId = 1,
CurrentClusterName = "UnitTesting",
HStatus = "True",
IStatus = "Success"
};
var modelFactory = Substitute.For<IModelFactory>();
modelFactory.CreateClusterManagementModel( /* args for model creation */).Returns(model);
var sut = new ManagementController(modelFactory);
var result = sut.Manage("1") as ActionResult;
You also need to think about what it is you're trying to test. By extracting the dependencies you're able to focus on the logic in your controller and focus your tests on that logic. It's very easy when you start using Mocks to get into a situation where you're not actually testing anything at all, other than whether or not you've set your Mocks up correctly. Remember, they are there to help you reproduce specific scenarios you need to force your production code to follow a particular flow, not to replace the logic contained in your production code.

View/Model data isn't refreshing/changing after post/postback, even though I'm using the PRG pattern

Update I have saved my problem a long time ago. The problem was that I was trying to call the view model on the wrong view method! I was calling the base view method (Document), instead of one of it's derived method (like NewDocument, PDFDocument, etc.) Thus it was only giving me the Documents data, which didn't change. I was looking and using the wrong view method all the time... Stephen, when you asked me
"Why do you create derived classes in a method but then return only the base class"
I couldn't answer the question at the time because I didn't even know myself, until I remember that originally, the method wasn't returning the base class. I only changed it so that it can work with the base view method, which was wrong in the first place!
That's what I get for only getting 3-4 hours of sleep in 3 days. Everything works right now. Thanks.
I'm having a hard time trying to figure out why the data in my view isn't changing after I do a post. Originally I was doing it via return View() and it worked, but since it was a partial view, the page didn't look great, so I was reading up and saw that it was better to do it by Post-Redirect-Get pattern (PRG) and to use an id value to retrieve the values instead of sending the entire model via Tempdata. I even used ModelState.Clear() and that didn't even work. When I debugged the code, the model only has the values from when I first called it.
Here's part of my Get controller:
NewDocument Get Controller
[DocumentAuthenticationFilter]
public ActionResult NewDocument(int? id = null)
{
// This doesn't work. The view keeps on showing the data from View(Services.CreateNewDocument()).
if (id != null)
{
return View(Services.GetdocumentViewModelData(DocEnum.Section.NEW_DOC_INDEX, (int)id));
}
// This works fine
return View(Services.CreateNewDocument());
}
And here's the post that calls the redirect:
NewDocument Post controller
[HttpPost]
[ValidateAntiForgeryToken]
[MultipleButton(Name = "action", Argument = "AddDocuments")]
//[OutputCache(Duration = 30, VaryByParam = "*")]
public ActionResult AddDocumentViewModel(FormCollection frm, DocumentViewModel dvm)
{
try
{
if (ModelState.IsValid)
{
int? DocID = Services.AddingNewDocument(dvm);
// See, I even tried to clear it.
ModelState.Clear();
return base.RedirectToAction("NewDocument", new { id = DocID });
}
else
{
// Display errors in the modal
}
return base.RedirectToAction("NewDocument");
}
And here's the old way I did it:
NewDocument Post controller
[HttpPost]
[ValidateAntiForgeryToken]
[MultipleButton(Name = "action", Argument = "AddDocuments")]
//[OutputCache(Duration = 30, VaryByParam = "*")]
public ActionResult AddDocumentViewModel(FormCollection frm, DocumentViewModel dvm)
{
try
{
if (ModelState.IsValid)
{
Services.AddingNewDocument(ref dvm);
dvm.NewRecordMode = DocEnum.Action.UPDATE;
// It worked, but only the partial view showed, and not the entire view.
return PartialView("_NewDocument", dvm);
}
else
{
// Display errors in the model
}
return base.RedirectToAction("NewDocument");
}
Could it be because I'm using a custom model binding?
My Custom Model Binding
public class BaseClassModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var modelType = bindingContext.ModelType;
var modelTypeValue = controllerContext.Controller.ValueProvider.GetValue("ViewModel");
if (modelTypeValue == null)
throw new Exception("View does not contain the needed derived model type name");
var modelTypeName = modelTypeValue.AttemptedValue;
var type = modelType.Assembly.GetTypes().SingleOrDefault(x => x.IsSubclassOf(modelType) && x.Name == modelTypeName);
if (type == null)
{
throw new Exception(String.Format("Derived model type {0} not found", modelTypeName));
}
var instance = bindingContext.Model ?? base.CreateModel(controllerContext, bindingContext, type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, type);
return base.BindModel(controllerContext, bindingContext);
}
}
EDIT: And here's the GetDocumentViewModelData code:
GetDocumentFromViewModelData
public static DocumentViewModel GetDocumentViewModelData(DocEnum.Section docType, int id)
{
switch (docType)
{
case DocEnum.Section.NEW_DOCUMENT_INDEX:
// NewDocumentTypeViewModel is a child to DocumentTypeViewModel
DocumentTypeViewModel nd = NewDocumentService.GetViewModelByID(id);
return nd;
case DocEnum.Section.PDF_DOCUMENT:
DocumentTypeViewModel pdfvm = PDFDocumentService.GetViewModelByID(id);
return pdfvm;
case DocEnum.Section.XLS_DOCUMENT:
DocumentTypeViewModel xlsvm = XLSDocumentService.GetViewModelByID(id);
return xlsvm;
}
return null;
}
Edit: Also adding the GetViewModelByID function
GetViewModelByID
public static DocumentTypeViewModel GetViewModelByID(int id)
{
docEntities db = new docEntities();
NewDocumentTypeViewModel vm = new NewDocumentTypeViewModel();
// Calls a stored procedure called Select_Documents_ByID(id) to get the note entry
// that was submitted.
List<Select_Documents_ByID_Result> prevNotes = db.Select_Documents_ByID(id).ToList();
StringBuilder sNotes = new StringBuilder();
foreach (var note in prevNotes)
{
sNotes.AppendFormat("{0} - {1}: {2}\n\n", note.CreatedDate.ToString("yyyy-MM-dd HH:mm"), note.username, note.Entry);
}
vm.PreviousNotes = sNotes.ToString();
return vm;
}
Edit: I did a direct creation of the view model inside the Get controller, and it's the same result. when i debugged the view itself, the values from the new view model don't show up. Instead, the values from the initial view model, View(Services.CreateNewDocument()), shows.
[DocumentAuthenticationFilter]
public ActionResult NewDocument(int? id = null)
{
// Right here I created the view model to test thing, but I'm getting the same results. Nothing has changed.
if (id != null)
{
var d = new NewDocumentTypeViewModel(1, "Help!");
// This property is from the base class, DocumentTypeViewModel
d.DocumentTitle = "Testing!";
return View(d);
// Inside the view itself, none of the values in the view model, including the one
// belonging to the base class. It still shows the initial values.
}
// This works fine
// Or maybe not...
return View(Services.CreateNewDocument());
}
Edit: I wanted to see if it was also doing the same thing for the initial call to the view return View(Services.CreateNewDocument()), and decided to change the value for documentTitle in the base class from New Document to a randomly-generated number, after the object has been created.
Here's the code for DocumentTypeViewModel's default constructor:
public DocumentTypeViewModel()
{
DocumentTitle = "New Document";
NewRecordMode = DocEnum.Action.ADD;
DocumentID = 0;
}
And here's the Services.CreateNewDocument() code where I change the DocumentTitle after the View Model has been created.
public DocumentTypeViewModel CreateNewDocument()
{
DocumentTypeViewModel dtvm = new DocumentTypeViewModel();
Random r = new Random();
dtvm.DocumentTitle = r.Next(5, Int32.MaxValue).ToString();
return dtvm;
}
Now in the View, when I call DocumentTitle:
<div class="label-text-group">
#Html.LabelFor(model => model.DocumentTitle)
#Html.EditorFor(model => model.DocumentTitle)
</div>
You would expect to see a randomly-generated number every time the View gets called. Nope, what you would see is "New Document". Weird.
It's seems that Services.GetDocumentViewModelData() is not exactly working correctly. It only carries the values created by the base class' constructor when a view is created, not any values that have been added or changed within GetDocumentViewModelData() itself. Why is that? What's going on? Please help anybody!
I have solved it. Look at the Update section on top. Thanks Stephen.

How to pass Interface as parameter for Controller class in Substitute

I am new to nSubstitute. And I am writing test method for my controller class. I have a TestMethod called GetDefaultStateTest() which having Substitute class as shown below
[TestMethod]
public void GetDefaultStateTest()
{
var _GetDefaultState = Substitute.For<CustomerController>(ICustomer cus);
Assert.IsNotNull(_GetDefaultState.GetDefaultState());
}
Because my controller class having parameterized constructor as below.
public class CustomerController : Controller
{
private readonly ICustomer _customer;
public CustomerController(ICustomer customer)
{
_customer = customer;
}
public string GetDefaultState()
{
// Get default state from settings table
List<tblSettings> settings = new List<tblSettings>();
// Calling service method GetSettings
settings = _customer.GetSettings();
var defaultState = from setting in settings
where setting.Desc == "DefaultState"
select setting.Settings;
string strState = "";
foreach (var oState in defaultState)
{
strState = oState;
break;
}
return strState;
}
}
While run the test method, it raise null reference issue. Because of parameter ICustomer is null
var _GetDefaultState = Substitute.For<CustomerController>(ICustomer cus);
How to resolve this problem.
If you are testing your controller class then you do not want to substitute for it, you want to use a real one (otherwise you'd just be testing a fake object "works" :)). Where you may want to substitute is for that class's dependencies, in this case, ICustomer.
[TestMethod]
public void GetDefaultStateTest()
{
var customer = Substitute.For<ICustomer>();
var controller = new CustomerController(customer);
Assert.IsNotNull(controller.GetDefaultState());
}
You may then want to fake out the ICustomer.GetSettings() method so you can test what your controller does with that data:
[TestMethod]
public void GetDefaultStateTestFromSettings()
{
var customer = Substitute.For<ICustomer>();
customer.GetSettings().Returns(somethingSensible);
var controller = new CustomerController(customer);
Assert.AreEqual(expectedDefaultState, controller.GetDefaultState());
}
As an aside, sometimes it makes more sense to use real objects (say, a real implementation of ICustomer) rather than substitutes. This will depend on how well-defined the interactions with the dependencies are, where you want to define the boundaries of your system under test, and how much confidence the test gives you that the system under test is working correctly. Or put more simply, whatever makes it easy and reliable to test. :)
Hope this helps.

How to unit test a custom actionresult

I'm trying to unit test a custom action result. I recently watched Jimmy Bogard's excellent MvcConf video ("put your controllers on a diet") http://www.viddler.com/explore/mvcconf/videos/1/ and have started to try and implement some custom action results. I've managed that without a problem, the ActionResult works fine at runtime but I'm having trouble trying to unit test them.
Unfortunately in the code download there are no unit tests for Jimmy's custom action methods... which make me wonder.
I realise that action methods just return instances of the ActionResult types and its the MVC framework that actually calls the ExecuteResult method, which of course is not available when running the unit test. So my unit test is now just creating an instance of my custom ActionResult and I then call ExecuteResult.
Unfortunatley in the ExecuteResult method of my custom ActionResult it is also calling the ExecuteResult method of a ViewResult that I passed it. At that point it blows up. How should I be mocking/stubbing these things to get my unit test working?
public class SendToAFriendActionResult : ActionResult
{
public const string INVALID_CAPTCHA = "You don't appear to have filled out the two words from the security image correctly to prove you're a human. Please try again.";
public const string INVALID_MODEL_STATE = "You don't appear to have filled out all the details correctly. Please try again.";
public const string CONTACT_FAIL = "Unfortunately we experiend a problem sending the link. Please try again later.";
public const string SEND_TO_A_FRIEND_FAIL_KEY = "ContactFail";
private RedirectResult _success;
private ViewResult _failure;
private readonly SendToAFriendModel _model;
private readonly bool _captchaValid;
private readonly MessageBuilderServiceBase _mbs;
public RedirectResult Success
{
get { return _success; }
set { _success = value; }
}
public ViewResult Failure
{
get { return _failure; }
set { _failure = value; }
}
public SendToAFriendActionResult(RedirectResult success, ViewResult failure, SendToAFriendModel model, bool captchaValid, MessageBuilderServiceBase mbs)
{
_success = success;
_failure = failure;
_model = model;
_captchaValid = captchaValid;
_mbs = mbs;
}
public override void ExecuteResult(ControllerContext context)
{
if (!_captchaValid)
{
Failure.TempData[SEND_TO_A_FRIEND_FAIL_KEY] = INVALID_CAPTCHA;
// On reaching this point I receive the error
// Object reference not set to an instance of an object
// as the MVC framework calls FindView
Failure.ExecuteResult(context);
return;
}
if (!context.Controller.ViewData.ModelState.IsValid)
{
Failure.TempData[SEND_TO_A_FRIEND_FAIL_KEY] = INVALID_MODEL_STATE;
Failure.ExecuteResult(context);
return;
}
_mbs.RecipientEmailAddress = _model.EmailRecipient;
_mbs.SendersName = _model.SendersName;
_mbs.Url = _model.URL;
var result = _mbs.sendMessage();
if (!result)
{
Failure.TempData[SEND_TO_A_FRIEND_FAIL_KEY] = CONTACT_FAIL;
Failure.ExecuteResult(context);
return;
}
Success.ExecuteResult(context);
}
}
Here's the start of my unit test ...
IMessageService _emailMessageSerivce;
IGalleryRepository _repository;
var stfModel = new SendToAFriendModel
{
SendersName = "Someone",
URL = "http://someurl.com",
EmailRecipient = "a-friend#somewherelse.com"
};
var failure = new ViewResult() {ViewName ="SendToFriend"};
const bool captchaValid = false;
var fakeControlllerContext = MockRepository.GenerateStub<ControllerContext>(null);
var stf = new SendToAFriendActionResult(null, failure, stfModel, captchaValid, null);
stf.ExecuteResult(fakeControlllerContext);
I've put comments in the SUT to show were the problem occurs.
I know I should be stubbing/mocking somehow but I just can't seem to resolve this.
From ASP.NET MVC 2 In Action (coauthored by Jimmy Bogard):
By taking that hard-to-test code out
of an action and putting it into the
Execute method of an action result,
you ensure that the actions become
significantly easier to unit-test.
That’s because when you unit-test an
action, you assert the type of action
result that the action returns and the
state of the action result. The
Execute method of the action result
isn’t executed as part of the unit
test.
Unit tests are designed to isolate behavior and concerns. You're mixing concerns by calling ExecuteResult from within your custom Action. Instead, I would have the SendToAFriendActionResult return the actual ActionResult (Failure or Success):
public ActionResult GetAction(..)
{
ActionResult result;
//logic here to determine which ActionResult to return
return result;
}
In your Controller:
public ViewResult SendToAFriend()
{
return SendToAFriendActionResult(null, failure, stfModel, captchaValid, null)
.GetAction();
}
This method will allow the MVC framework to do its job and isolates those concerns outside your custom ActionResult. Your test should assert that the correct type of Action, failure or success, is returned based on the parameters you set going in.

Using Request.Files.Count with TestControllerBuilder from MvcContrib?

I have a controller action in ASP.NET MVC that handles uploaded files. However, it seems there is no way to call Request.Files.Count while using MvcContrib's TestControllerBuilder.
I know I can work around this by abstracting Request.Files. My questions are:
Is it indeed the case that there is no direct way to call Request.Files.Count when using the TestControllerBuilder? Or am I doing something wrong?
Is there a way to stub the call to Request.Files.Count while using TestControllerBuilder using Rhino Mocks?
Do you think I should submit a request or patch for handling Request.Files.Count to MvcContrib?
Example code:
I want to make sure that there is at least one file in the Request.Files collection so I have the following conditional in my action:
public class MyController : Controller {
public ActionResult Upload() {
if (Request.Files == null || Request.Files.Count == 0)
ViewData.ModelState.AddModelError("File", "Please upload a file");
// do stuff
return View();
}
}
I am using the TestControllerBuilder from MvcContrib to create the test double for my controller tests. However, the call to Request.Files.Count always seems to throw a an exception. For example running the following NUnit test throws a NotImplementedException during the call to controller.Upload() at the call to Request.Files.Count:
[Test]
public void Upload_should_return_default_view_given_one_file() {
MyController controller = new MyController();
TestControllerBuilder controllerBuilder = new TestControllerBuilder();
controllerBuilder.InitializeController(controller);
controllerBuilder.Files["file"] =
MockRepository.GenerateStub<HttpPostedFileBase>();
var result = controller.Upload() as ViewResult;
Assert.That(result.ViewData.ModelState.IsValid, Is.True);
result.AssertViewRendered().ForView(string.Empty);
}
I've also attempted stubbing the call to Request.Files.Count to no avail (I'm using Rhino Mocks). None of the below work (even if I change controller and/or controllerBuilder to a stub):
controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);
Thanks
I submitted a patch on Github to MvcContrib mantainers, but the changes are very simple to make, the problem is that HttpFileCollectionBase is not implementing Count() and this[int index] methods so they must be overriden by the WriteableHttpFileCollection in MvcContrib.
I paste the code here for completeness, that must be added to WriteableHttpFileCollection class:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
I've used this approach to solve the problem.
SetUp the test:
string fileName = "Test 1.pdf";
FileStream stream = File.OpenRead("log4net.config");
MockRepository mock = new MockRepository();
builder.Files[fileName] = mock.CreateMock<HttpPostedFileBase>();
using (mock.Record())
{
Expect.Call(builder.Files[fileName].FileName)
.Return(fileName);
Expect.Call(builder.Files[fileName].ContentType)
.Return(contentType);
Expect.Call(builder.Files[fileName].ContentLength)
.Return(Convert.ToInt32(stream.Length.ToString()));
Expect.Call(builder.Files[fileName].InputStream)
.Return(stream);
}
using the mock:
foreach(string key in Request.Files.AllKeys)
{
int lenght = Request.Files[key].ContentLength;
if (lenght > 0)
{
Document document = new Document();
string fileName = Request.Files[key].FileName;
byte[] content= new byte[Convert.ToInt32(lenght)];
Request.Files[key].InputStream.Read(content, 0, content.Length);
document.SetContent(content);
document.MimeType = Request.Files[key].ContentType;
// do whatever you want...
}
}

Resources