What's the easiest way to write a unit test that sends Request.Form data to my controller? - visual-studio-2010

Basically I want to set 20 or so Request.Form values, send a POST to my controller, and then check the result.
I found a couple articles such as this one which describe how you can do this with a combination of NUnit, MVCContrib, and Rhino Mocks. But I don't know if this is truly necessary.
It would seem that Visual Studio 2010 and ASP.NET MVC 2 should be able to do this natively and display the results in the little "Test Results" window. In fact, when I create a new unit test with the wizard, it comes up with this...
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("G:\\Webs\\MyWebsite.com\\MyWebsite", "/")]
[UrlToTest("http://localhost:43383/")]
public void PaypalIPNTest()
{
BuyController target = new BuyController(); // TODO: Initialize to an appropriate value
ActionResult expected = new EmptyResult(); // TODO: Initialize to an appropriate value
ActionResult actual;
actual = target.PaypalIPN();
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
Is it possible to feed target.PaypalIPN() my Request.Form variables based on the above code? Or do I need to rely on 3rd party libraries to get this done?

In fact, when I create a new unit test with the wizard, it comes up with this
Yes, and all that you can keep from this is the method signature. The method body is useless.
So let's start by looking at this:
Is it possible to feed target.PaypalIPN() my Request.Form variables
By reading this sentence I assume that your controller action looks something like this:
[HttpPost]
public ActionResult PaypalIPN()
{
string foo = Request["foo"];
string bar = Request["bar"];
... do something with foo and bar
}
So the first is to improve this code by introducing view models:
public class MyViewModel
{
public string Foo { get; set; }
public string Bar { get; set; }
}
and then modify your method signature to:
[HttpPost]
public ActionResult PaypalIPN(MyViewModel model)
{
... do something with model.Foo and model.Bar
}
Now your controller is abstracted from any HttpContext infrastructure code (which really should be left to the framework, it is not your controller actions responsibility to read request parameters => that's plumbing code) and unit testing it is really a simple matter:
[TestMethod()]
public void PaypalIPNTest()
{
// arrange
var sut = new BuyController();
var model = new MyViewModel
{
Foo = "some foo",
Bar = "some bar",
};
// act
var actual = sut.PaypalIPN(model);
// assert
// TODO:
}
OK, this being said, here we dealt with some really simple controller action. For more advanced scenarios you really should consider using a mocking framework. Personally I use MvcContrib.TestHelper with Rhino Mocks to unit test my ASP.NET MVC applications.

I have another approach to test my MVC application, first I used Dev Magic Fake to fake any underline layer under the controller until the application is running and the business is approved and then I replace the fake code with TDD approach based on approved requirements
See Dev Magic Fake on CodePlex:
http://devmagicfake.codeplex.com/
Thanks
M.Radwan

Related

How to access the Session in MVC.Net 4 from different Thread

I have a MVC.Net4 Application in which i have Longrunning backround operations which is why i use the System.Threading.Tasks.Task Class.
I start the Tasks after the User clicked a certain Button on the GUI, from that Task im going to use async methods from a intern API which i need to await. This is all working.
public ActionResult DoAsyncAction()
{
//ReturnValue that needs to be further populated by the async action in productive environment
var arv = new AsyncReturnValue
{
ProgressBar = new ProgressBar {Action = "SomeAction", User = "SomeUser"}
};
var t = new Task<AsyncReturnValue>(DoAction, arv);
//Add a Progressbar before Task starts so i can visualize the process on the view
HttpContext.GetSession().ProgressBars.Add(arv.ProgressBar);
//from my understanding this is similar to an event that gets triggered when my DoAction Method finished so i need to remove
//the progressbar there again since the process will be finished in that case
t.ContinueWith(DoActionkComplete);
t.Start();
//Returns the User to the Index Page while the Task is processing
return View("Index");
}
Now what i really want to do is visualizing the operation. I use jQuery Progressbars on the GUI and my Own ProgressBar Object in the Session for this. I have a List of ProgressBars on my Session and a PartialView strongly Typed to a List of those ProgressBars.
ProgressBar Class:
public class ProgressBar
{
public string Action { get; set; }
public string User { get; set; }
}
PartialView:
#using AsyncProj.Models
#model List<AsyncProj.Models.ProgressBar>
#{
ViewBag.Title = "ProgressPartial";
}
#{
var foo = (MySessionObject) HttpContext.Current.Session["__MySessionObject"];
foreach (var pb in foo.ProgressBars)
{
<div style="border: 1px solid black">
<p>#pb.Action</p>
<div id="progressbar">This will be turned into a ProgressBar via jQuery.</div >
</div>
}
}
And then the Object i have in my Session:
public class MySessionObject
{
public List<ProgressBar> ProgressBars { get; set; }
public string User { get; set; }}
Whenever i start a new Task i will add another ProgressBar to that List, which works just fine.
No where i get into Troubles is when i want to Remove the ProgressBars from Session again.
In the DoActionkComplete Method which i set in Task.ContinueWith() i want to Remove the ProgressBar corresponding to the finished action. I have the ProgressBar Ready there, its stored in my AsyncReturnValue Class which i have in the Task.Result at this point:
public class AsyncReturnValue
{
public ProgressBar ProgressBar { get; set; }
}
In this Method i would like to remove the Progressbar from the Session with
HttpContext.GetSession().ProgressBars.Remove(pbToRemove). But the problem with that im still operating on a different Thread so i have no valid HttpContext there and my SessionObject is null on that Thread.
This is what my DoActionComplete Method looks right now:
public void DoActionkComplete(Task<AsyncReturnValue> t)
{
//i set the user hardcode because its only a demo
DeleteProgress.Add(new ProgressBarDeleteObject {ProgressBar = t.Result.ProgressBar, User = "Asd123"});
}
I created a Workaround where i have a static List of Progressbars on my Controller. In the DoActionComplete Method i add the ProgressBars i want to delete to that List. I need to use polling (with jQuery $.get() and setinterval) in order to delete them.
I have a custom Class for the DeleteList on which i can set a Username so i know who is the Owner of that ProgressBar and only show it to him, else everyone would see it because its Static.
public class ProgressBarDeleteObject
{
public ProgressBar ProgressBar { get; set; }
public string User { get; set; }
}
Dont get me wrong, my workaround works just fine but i want to know the clean way. From what i know static Lists on Controllers could technically grow very big and slow the site down. Such Lists also lose its entries when the ApplicationPool restarts the Application.
So my Actual Question would be how can i access a HttpContext SessionObject from a different Thread like i'm using? And if its not possible, what would be the proper Way to achieve what i want?
So my Actual Question would be how can i access a HttpContext SessionObject from a different Thread like i'm using?
That's not possible.
And if its not possible, what would be the proper Way to achieve what i want?
First, let's back up to the original scenario. The problem is here:
I have a MVC.Net4 Application in which i have Longrunning backround operations which is why i use the System.Threading.Tasks.Task Class.
That's the wrong solution for that scenario. The proper solution is to have a reliable queue (Azure queue / MSMQ) with an independent background process (Azure webjob / Win32 service) doing the processing. This is a more reliable solution because any work you toss onto the ASP.NET thread pool may be lost (especially if you don't inform ASP.NET about that work).
Once you have this architecture set up, then you can use SignalR to communicate from your web server to your clients. SignalR will use polling if it has to, but it can also use more efficient methods (such as websockets).
You can specify the SynchroniztionContext that the ContinueWith task continues on and then you should be able to access the progress bars. Try changing your t.ContinueWith(DoActionkComplete); call to
t.ContinueWith(DoActionkComplete, TaskScheduler.FromCurrentSynchronizationContext());
If you are using .NET 4.5 you can rewrite your method with async\await
public async Task<ActionResult> DoAsyncAction()
{
//ReturnValue that needs to be further populated by the async action in productive environment
var arv = new AsyncReturnValue
{
ProgressBar = new ProgressBar {Action = "SomeAction", User = "SomeUser"}
};
//Add a Progressbar before Task starts so i can visualize the process on the view
HttpContext.GetSession().ProgressBars.Add(arv.ProgressBar);
var result = await Task.Run(DoAction());
//i set the user hardcode because its only a demo
DeleteProgress.Add(new ProgressBarDeleteObject {ProgressBar = result.ProgressBar, User = "Asd123"});
//Returns the User to the Index Page while the Task is processing
return View("Index");
}
And if you make the DoAction method async as well, you can remove the Task.Run part as that uses up a thread from the thread pool.

Trying to use Rhino Mocks in VS2010 -- tests don't run

I have a unit test that works just fine when it is hitting a real object that hits teh real data storage. Something like that:
[TestMethod]
public void ATest()
{
var p = new Provider();
var data = p.GetData();
...
}
This test gets executed in all modes, gets the data back and does everything that is exected from it. Now, say I want to mock the provider using Rhino Mocks. Provider class implements IProvider. So I go and write something like this:
[TestMethod]
public void ATest()
{
var p = MockRepository.GenerateStub<IProvider>();
...
var data = p.GetData();
...
}
But now when I try to debug this test, it doesn't work. At all. I mean, I put a breakpoint on the first line of this method (on the '{' itself) and it is not being hit. Kind of weird...
I am all new to Rhino Mocks, maybe I am missing something obvious?
You didn't define a return value for the GetData call on the mock. Try something like this:
p.Stub(s => s.GetData()).Return(testData);

using Moq - void return type method Unit test

I am writing unittest for void method actually that method load the collection in
ViewData["CityList"] method is
public void PopulateCityCombo() {
IEnumerable<Cities> c= service.GetCities();
ViewData["CityList"] = c.Select(e => new Cities{ ID = e.ID, Name = e.Name});
}
now i do not know how to unit test using Moq since controller method is void and not returning data, can any one tell i will achive that.
On a side note, I would shy away from using ViewData within controller methods as per your example. The ViewData dictionary approach is fast and fairly easy to implement, however it can lead to typo's and errors that are not caught at compile time. An alternative would be to use the ViewModel pattern which allows you to use strongly-typed classes for the specific view you need to expose values or content within. Ultimately giving you type safe and compile time checking along with intellisense.
Switching to the ViewModel pattern would allow you to call the PopulateCityCombo() method from your controller to populate a ViewModel that in turn would passed to the corresponding view.
From there you would need to inject a mock service layer into your controllers constructor from your unit test.
// arrange
var mock = new Mock<servicelayer>();
mock.Setup(x=>x.GetCities()).Returns(expectedData);
var controller = new YourController(mock.Object);
// act
var result = controller.ControllerMethod() as ViewResult;
var resultData = (YourViewModel)result.ViewData.Model;
// assert
// Your assertions

MVP with Moq - loading a mocked view

I've read a lot about mocking/stubbing/faking - and still hit my mental roadblocks.
I'm trying to adapt MVP (Model View Presenter) with a "fun" weight loss tracking system I'm building for my own Fatty McFatter-self. I'm trying to TDD & 'by the book' this but hit many mental blocks and stall out.
I am building my Presenter and mocking my Service & View at the moment. Here's my test: again note: service and view are mocked with Moq
[Test]
public void GetLog_WithExistingDate_ViewSetWithExistingLog()
{
WeightLogModel model = new WeightLogModel
{
EntryDate = DateTime.Now,
Waist = 42,
Weight = 242
};
service.Setup(x => x.GetLog(It.IsAny<DateTime>())).Returns(model);
presenter.Display(DateTime.Now);
IWeightLogView myView = view.Object;
Assert.AreEqual(model.Weight, myView.Weight);
}
and in my Presenter - this is my Display method:
public void Display(DateTime date)
{
var weightLog = service.GetLog(date);
if(weightLog == null) return;
View.EntryDate = weightLog.EntryDate;
View.Waist = weightLog.Waist;
View.Weight = weightLog.Weight;
}
Now - if I debug as Display is being called - I see the weightLog is filled with the correct info I've setup in the mock. But as it's suppose to set View.EntryDate, View.Waist, etc - the View values never change. They stay zero or 0001/1/1
Is there some way to make it work? Or is this just a bad test and I'm floundering in confusion?
Thanks to Phil for starting me in motion. Although I didn't want to explicitly set what I was going to return - I wanted the mock view to behave like my view. You can have the mocked setter behave as normal by calling SetupProperty --> view.SetupProperty(x => x.Weight) //in my case... here's the test that will now pass asserting the weight was set
[Test]
public void GetLog_WithExistingDate_ViewSetWithExistingLog()
{
WeightLogModel model = new WeightLogModel
{
EntryDate = DateTime.Now,
Waist = 42,
Weight = 242
};
service.Setup(x => x.GetLog(It.IsAny<DateTime>())).Returns(model);
// I ADDED THIS ONE LINE
view.SetupProperty(x => x.Weight);
presenter.Display(DateTime.Now);
IWeightLogView myView = view.Object;
Assert.AreEqual(model.Weight, myView.Weight);
}
You are not showing all your setup code here, nor the dependencies between classes.
However if you are indeed mocking the view called "myView", it's going to return what you have the mock set up to return, or defaults for each type if you haven't specified anything for it to return (which sounds like what is happening).
From your comment:
I am trying to setup the
service.GetLog(date) to return the
WeightLogModel I have in the test. My
thinking is that doing so - would make
that WeightLogModel available in my
presenter
So far that seems like it is working from your original question.
to assign to my mocked view - where
View.EntryDate = weightLog.EntryDate
.... in this case weightLog is what is
setup in the test.... I hope I'm clear
as to where my head is... I'm not
saying I'm right - this is what my
thinking is though.
Where are you going wrong is where you say "to assign to my mocked view". It's not clear from your code whether or not the View property is in fact your mocked view (because your code is incomplete).
Although, in this case, it actually doesn't matter. If the View property is in fact a mock, it will only return what you tell it to return--its properties are not going to behave like "normal" properties.
So the following will fail without explicit setup:
mockView.MyProperty = "hello";
Assert.AreEqual("hello", mock.MyProperty);

GUI Pattern Question: PropertyChangeListener vs. Specialized View Interface

I'd like to pair a Model with it's View through an interface. I want to control when and how often the view is updated. So something like PropertyChangeListener wouldn't work well (where an event is fired after each property is set).
I'm not developing for a specific GUI framework. The goal here is the ability to swap out different GUI front ends (right now for testing, but might be useful later for different versions of the app). These might be Swing, or it might be a web browser (via GWT, for example).
Below is my approach. The view implements an interface to provide a method to update. This is triggered by the controller when it determines it's done updating the model. This still feels ok to me, since the Controller is only interacting with the view through the model, the controller is not dependent on a particular implementation of the View.
So, I guess my question(s) are
does this work well?
Is this standard practice?
Does this pattern have a name?
Rough code sample (Java):
// Controller, manages Items (the model)
class ItemList {
void addItem(Item item) {
}
void doStuffWithItems() {
// perform some set of operations, such as sorting or layout
for (Item item : items) {
// ....
}
// now with everything in it's final position:
for (Item item : items) {
item.updateView();
}
}
}
// Model
class Item {
private int top;
private int left;
private int width;
private int height;
// Can remember it's previous position/size:
public void savePostion() {
}
// And recall it for the Controller to use:
public public Position getSavedPosition() {
}
// Plus some other useful functions:
public boolean intersectsWith(Item other) {
}
public void updateView() {
this.view.update();
}
void setView(ItemView view) {
this.view = view;
}
}
// Interface used by View implementations
public interface ItemView {
// Trigger the view to reflect the current state of the model
void update();
}
// Example, as a Swing component
class ItemComponent extends JComponent implements ItemView {
private Item item;
public ItemComponent(Item item) {
this.item = item;
item.setView(this);
}
// ItemView#update
public void update() {
// update the component's size/position
setBounds(new Rectangle(item.getLeft(), item.getTop(), item.getWidth(), item.getHeight()));
}
#Override
public void paint(Graphics g) {
// ...
}
}
I would avoid forcing the View to implement an interface only for change notification. Create a separate "update now" event on the model instead.
The model should not be controlling or know about the view directly. The view should register a callback with the controller so the controller can tell the view when to update, that's why its the controller. You could have the model allow external listeners for a modelChangedEvent. Then the view could register with the model in that respect without the model knowing there was a view. See the J2EE blueprint for MVC and how there is an indirect event notification of state change in the model.
For traditional applications that run on the desktop of a computer I recommend variants of the Passive View. The class responsible for creating and managing the form is a thin shell that passes events to the UI Object. The UI_Object interact with the form via a interface. In term the UI Object implements a UI_View Interface and registers itself with a View Controller that is situated lower in the object hierarchy.
The UI_Object then execute object implementing the Command Pattern which modifies the model. The command object can interacts with the various views via the interfaces exposed by the View Control.
What this does is allow you to rip off the form classes and replace them with stub classes that implement the form interfaces. The stub classes are used for automated testing especially for integration tests.
The interfaces precisely define the interaction between the Form, the UI_Object, Commands and the views. They can be designed to be relatively language agnostic so they can make porting between platform easier.
What you are missing in your example are command objects. You need this structure
ItemViewForms
ItemViewImplementation
ItemViewFormInterface
ItemViewCommands
ItemViewInterface
MyModel
Incorporate ItemList in the ItemViewImplementation
ItemComponent would register with the ItemViewImplementation using the ItemViewInterface.
The sequence of events would look something like this
User wants to update the Item
Clicks on the UI (assuming that UI
involves clicking with a mouse)
The Form tells the
ItemViewImplementation through the
ItemViewInterface that X has been
done with Y parameters.
The ItemViewImplementation then
creates a command object with the
parameters it needs from Y.
The Command Object take the Y
Parameters modifies the model and
then tells the
ItemViewImplementation through the
ItemViewInterface to update the UI.
The ItemViewImplementation tells the
ItemViewForms to update the UI
through the ItemViewFormInterface.
The ItemViewForms updates.
The advantage of this approach is that the interaction of each layer is precisely defined through interfaces. The Software ACTIONS are localized into the command objects. The Form layers is focused on display the result. The View layer is responsible for routing actions and response between the Commands and Forms. The Commands are the only things modifying the model. Also you have the advantage of ripping off the Forms Implementation to substitute any UI you want including mock object for unit testing.

Resources