Shane Bauer Blog
.NET, ASP.NET and Software Development

Subversion, TeamCity, and Rake = Wow

October 28, 2008 15:31 by sbauer

Whenever I start a new project there are certain things that I always need to do. I need to setup the source code repository, create a basic project structure, create a build script to build the project, and setup the project on a build server.

A few months ago I realized just how much I hated doing all of this. Setting up the repository was the easiest part. I've been using Subversion for years. Instead of hosting my own subversion server, I use a third party. I'll let them manage the server, subversion upgrades and the backups. Because of this, setting up the repository was basically logging into a control panel, filling out a form, and that's basically it. However, after this was completed, the tasks became much more redundent. 

For the longest time I used NAnt for my build engine. It is a good tool, no doubt. The problem is I hate XML. I hate it. It's not the language itself really. It's how people use XML. NAnt uses XML as the way to write the build script. I hated creating the scripts and I hated modifying them.

Of course, my XML troubles didn't end there. I used CruiseControl.net as my CI (build) server. The application itself is OK. It's not great and has aged quite a bit. By far my biggest problem with CC.NET is the process of adding a new project. In order to add a new project to CC.NET, you must modify an XML file. If you have many projects configured, that file may be quite large.

I don't know about you, but after setting up my build script and setting up the project in CC.NET, I'm pretty tired of looking at XML.

Taking a look at TeamCity

After reading a ton of blogs and twitter messages from people talking about TeamCity, I decided to give it a shot. I wasn't really sure what to expect. I thought it would be good as I'm a huge ReSharper fan (the same company that makes ReSharper also makes TeamCity), but didn't really know if it would fit my needs.

Fortunately, JetBrains (makers of TeamCity) markets a version of TeamCity targeted for smaller teams that doesn't cost a thing. I grabbed it, installed it on a VM, and played around. To make a long story short, I'm still using it. TeamCity is a really nice CI server. It's very extensible and configuration is a breeze. You can add projects and build configurations straight from the browse. No need to modify XML files. TeamCity supports a number of different version control systems and build environments out-of-the-box. NAnt, MSBuild, Ant, and command-line are just a few. Because of this I was able to migrate my project from CC.NET to TeamCity in no time. 

Replacing NAnt with Rake

After deciding to go with TeamCity, I felt pretty good. I had solved one problem. I cannot tell you how much time I've saved because of it. After a while, though, I started to look for replacement options for NAnt. Like I said before, I like NAnt, but I wanted something better than XML. After doing some research, I decided to look into Rake, a build tool programmed in Ruby. I noticed a few .NET developers using Rake successfully. One evening I loaded my NAnt build script and replicated the entire script using Rake. I've done some work in Ruby so it didn't take that long to convert everything over. Obviously, you don't have the pre-made nant tasks, but creating a reusable framework that calls the executables for various tools (msbuild, nant) wasn't too bad. After I got it working locally, I modified my existing build configuration in TeamCity to call the new rake script. Initially, I used the rake runner in TeamCity. After a while, I wasn't getting the results that I wanted so I switched to the simple command-line runner. After tweaking a few minor things, I was done. 

Looking Back

I'm really satisifed how things turned out. TeamCity is a joy to work with. Managing Rake build scripts instead of XML files just feels right. If you're looking for a replacement or you're just getting into this territory, you should really take a look at TeamCity and Rake.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | .Software Development
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Customer Service and How Manning Publications Let Me Down

April 29, 2008 10:21 by sbauer

I'm a fan of NHibernate. I've been using it for a little while and have grown to like it. Last year I found out that an NHibernate book was in the works from Manning. Being a huge fan of NHibernate and Manning, I decided to purchase this book from the "Manning Early Access Program". Basically, MEAP is a program they setup that gives customers early access to the chapters before they are published. You can either buy the MEAP e-book or the e-book and the print book. Obviously, the print book would be mailed to you once the book is published. The MEAP e-book and print option is usually just a little more expensive (~$5) than a print copy that you would buy in the store. Anyway, I purchased the e-book and print option in June of 2007.

All Is Well

After I purchased the book, a download link was sent to me pretty quickly. I downloaded the available chapters of the book and was pretty satisified. The MEAP program was pretty cool. I could read the book and then give feedback in the forum. Not a bad idea.

Delays and Moving

As time progressed I noticed the book kept getting pushed back. Not a big deal to me since I had most of the chapters, but I noticed I was quickly approaching my move date. Finally, in January of 2008, the time had come to move. 

Customer Support, Please

A month after moving, I remembered I had this book order floating out there.  Before I forgot about it, I went to Manning's site to see if I could change my address. Since I didn't find any such tool, I found their customer support section and sent an e-mail. This was on Feb 24th. On March 4th, I still did not receive a reply. I sent another e-mail reminding them that I needed to get this change as I won't be able to get to the old address. After this e-mail I waited quite some time and didn't receive a response. This time, however, I didn't sent another e-mail. I went to the site again and found their customer support number. I dialed the number and ended up listening to their voice messaging system. I left a message with my name, number and issue. 

Still Need That Support

I, again, waited some more. By now, we're in April and I still haven't heard from a single person there. No e-mail, no phone call, no voicemail on my end. Nothing.  Now I'm a little bitter. I sent another e-mail saying basically the same thing, with the added bonus of saying how many times I've tried contacting this company. I also copied the customer support manager (I think that's his title) on it as well. This was sent on April 17th. Can you guess what happened next? If you guessed "No response", you're right! Good job! You win half of a Manning book. Now, I challenge you to contact them for the rest. Good luck.

Seriously, though, Support? Please?

As of last week, I was still without support. Meanwhile, I've contacted the author. He told me that he forwarded my request to his contact. Another author also forwarded my request to his editor. Nothing. In my head I'm thinking, "Now what?". Well, I just did everything all over again. I left another voicemail. I sent another e-mail. This time, though, I copied every e-mail address on the site. I copied the webmaster, the support department, the support manager, and the infringement department. I even forwarded the e-mail to the support manager's personal e-mail address that he lists on the site. (I'll get into this more later) This was was on April 25th. Yeah, not too long ago, but still a few business days. Guess what? Yup, nothing.

A Little Research

As of today, April 29th, I'm still in the exact place I was when I started this adventure two months ago. Because of this, though, I've spent some time researching other situations. Apparently, I'm not the only one to have this issue.

Excuses, Excuses, Excuses

If you read their customer support section, you'll notice that they a blurb about their e-mail support. They say that if you don't receive a response from them in a few days, e-mail someone else or call the number. The excuse they're using is "spam filtering". The support manager even put his own gmail account on the site so people could e-mail that to get around the filtering. I sent a copy of the e-mail to that address as well. No response. I pointed out several examples of customers not getting e-mails. Is the spam filter blocking every e-mail? If it was, don't you think it would make sense to maybe get a new spam filter or stop using one? Or if that's so impossible, maybe they should just get rid of e-mail support and ask people to call instead. Oh, that's right, though. They don't call back either. They probably didn't get my messages. The spam filter must block those too. 

In Summary

I've learned quite a few things from this experience.

- EAP is a good idea.
- Their customer support is a joke.
- It's unlikely that I'll buy another Manning book. There are a few EAP books that I like (DSL, Art of Unit Testing, ASP.NET MVC), but as it stands right now, I will not be buying them. I'm not going to spend $50 on a product when I can't even get recognized by the company.
- They have some good books, but...
- Their customer support is a joke.

The Numbers

Total E-mails Sent: 6
Total Phone Calls: Countless
Total Voice messages left: 2
Total Sandbox Forum Posts: 1
Number of e-mails/calls/voice mails received: 0

Update 4/29/2008 - 3:04pm: Just sent two new e-mails: one to an alternate e-mail found on the site, and an e-mail to two other Manning contacts.


Currently rated 1.0 by 1 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tip: Register Windsor Dependencies via Code, instead of XML

April 25, 2008 15:32 by sbauer

One thing I never really liked is component registration via XML. If you were to remove a class, and forgot to remove the class from your configuration, you would find out at runtime. I'd much rather find out at build time and get the benefits from the refactoring tools.

You can do this by registering your components in code. Typically, you would register your components during application startup.

container.AddComponent<IPlayerService, PlayerService>();
container.AddComponent<IBallparkService, BallparkService>();

You have several different options when adding components. In my example, I'm just specifying a service (the interface) and the concrete class (BallParkService) that will be used. When my application needs a IBallParkService, Windsor will pass along the BallparkService. Since I didn't specify a lifestyle, the default transient lifestyle will be used. The transient lifestyle will create a new instance for every call. There are other options, though, that you can use depending on your needs. 

 


Currently rated 1.0 by 1 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Learning MVC is not hard; Learning how to use it correctly is

April 24, 2008 13:31 by sbauer

I was browsing the MVC forum on the ASP.NET site and found a topic asking about MVC training. Since the Microsoft ASP.NET MVC framework has not been released yet, you would be hard pressed to find a training class dedicated toward their framework. MVC is not new, though. There are other classes out there that may not target an actual implementation or they'll target existing implementations (MonoRail, Spring, Structs).

Beyond that, though, I found this post pretty interesting:

 in my opinion it´s not so complex as ASP.NET WebForms (because no ViewState and no Postback - its just a ping pong with the view and the controller ;) (and the model ;) )).

He's right. ASP.NET MVC does not have such complex areas as ViewState. You just write a controller, write a method that becomes an action, create and edit your view, and then hook them up. Pretty simple, right? Maybe.

ASP.NET WebForms - What was the goal?

The WebForms project model tries hard to be developer friendly. It takes HTTP and tries to tuck it away. Instead of worrying about a stateless envrionment, WebForms makes the developer believe that it is quite stateful. ViewState, for example, can help you store state. Even the controls that render simple HTML can remember their values. WebForms, in a basic view, is Windows Forms for the web. You have state, controls and even an event lifecycle for a page. Theoretically, Windows Forms developers should be able to migrate to web projects and see some familiar areas. All is good in the world.

WebForms Can Be Sneaky

After a while, though, that great feeling starts to go away for many developers. ViewState becomes awkward. The controls don't generate the HTML that I want it to. I can't seem to test my pages in a non-awkward way. In the end, the WebForms abstraction has become more complicated than the entity that was being hidden. For some developers, the WebForms model works. If it works for you, then great, continue to use it. If not, Microsoft has heard your call.

Welcome, ASP.NET MVC

First off, MVC is not some new thing Microsoft invented. Yes, they created their own MVC framework, but they didn't create the concept. ASP.NET MVC isn't even the first framework for .NET. MonoRail, another MVC .NET implementation, has been around for quite some time. 

The MVC pattern separates the application into three layers: model, view, and controller.  The model is your domain model. If you were developing a store, you would probably have models representing an order, customer and a product. The view is your user-interface. This is what your end-user will see. In a web application, your view typically contains HTML. A controller is typically a class that controls the interaction between the model and the view. Once a controller action has been called, it has logic in place that ties both the model and view together. 

Separation of Concerns

The MVC model promotes separation of concerns (SoC). Your model contains the business logic, not presentation logic. Your view should contain presentation logic, not business logic. Why did I say should? Well, it's up to the developer.

Learning How to Use MVC Correctly is the Most Difficult Part

The framework itself is not hard. Learning how to use a framework properly is hard. Anybody can create a controller, add an action, and then throw text onto a view. Learning how to do that the correct way will take time, though. Sure, you could migrate your WebForms application and place your Page_Load event in an action, create better URLs and call it complete. What are you really buying yourself, though? If you have business logic in your controller, the Single Responsibility principle is now broken because the controller is doing 20 different things. In the end, the only thing you've done is migrated from one framework to another and lost a few features you didn't like. That's it. You can't fully harness the testability features of MVC.

Update your Bookshelf or Get to Class

The best thing you can do is learn software design techniques that are not tied into a specific technology.  Take a class on software design, buy a book on software design, read about design patterns and when to use them. Learn about and practice Test-Driven design. There are so many options. 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Testing your ASP.NET MVC Controllers with Moq and xUnit.net

April 23, 2008 15:47 by sbauer

I went to the CMAP Code Camp a few weeks ago, and sat in a session about mocking. I wasn't new to mocking by any means, but I thought it would be useful to listen to other thoughts/opinions. Code Camp sessions, by the way, are a great way to improve your skills. Even if you're not new to a concept, that doesn't mean you're not going to get anything out of it. Code Camp sessions are not like college classes. The speakers don't just feed you information and tell you to shut-up. The entire environment promotes discussion. Had a problem with something? Would like a second opinion on an idea? Speak up.

Anyway, the speaker (Scott Allen) walked through a few real-world examples. These examples included some very basic unit tests using xUnit.net. After a while, though, he started mocking a few services with Rhino Mocks. Having used Rhino Mocks previously, I knew what was going on. Right before the end of the session, he took one test and coded it using Moq, another mocking framework that utilizes some of the new C# 3.0 syntax sugar. Before this session I never really took a serious look at Moq, or even xUnit.net. Today, I decided to try both.

The New'ish Guy - xUnit.net

Another unit testing framework? Yes, but it's not the same thing packaged up with a new name. xUnit.net has added some new things (Assert Exceptions without Attributes), modified some things (Fact attribute, instead of Test) and removed some things (no TestFixture attribute, no SetUp or TearDown attributes). 

I know, I know. Why be different? Why have a Fact, instead of a Test? It's interesting because I felt the same way. Everyone uses the Test attribute, why make it Fact now? After using it for a while, it just makes sense. From my standpoint it just promotes better test names. I feel some people create test names that don't fully tell the whole story. Fact makes me want to type out a name that should represent a fact. For example, I will be posting some code that will test a method to make sure that, if a domain entity has not been found, will redirect the user. Some people may feel inclined to write "TestRedirect". But you're not testing a redirect really. We're using a framework that we're not responsible for so the redirect code should work. What we're trying to test is the interaction between the domain and the controller. When my domain entity is null, I want to call code that redirects the user to a certain page. Wouldn't a test named "View_Action_Should_Redirect_User_To_Index_If_Ballpark_Is_Not_Found" or something like that make more sense? That's a fact.

A Little About Moq

Moq is a mocking framework that takes advantage of some new language features and helps reduce lines of code in certain areas. It takes certain aspects like Record and Playback, and just hides them behind the scenes. Moq is actually pretty cool. I wouldn't call it completely mind blowing, but it's pretty neat. The ability to use new language features and it's own features to make your tests less verbose is a good thing.

The Example

I'm going to use the scenario I mentioned above. I have a ballpark controller. In it I have an action called "View" that gets a ballpark based on the id passed to it. If the ballpark is found, I want it to display the ballpark details using the "viewballpark" view. However, if my ballpark is not found, I just want to redirect the user to the index action in the same controller. Obviously, this may not be what you want to do. You may want to display an error page. For this example, though, this is what we want to do. I'm not going to use the TDD approach for this example as I have my controller action already coded. I'm going to show you the controller action, a failing test, and then a test that passes.

First, the controller action:

 

public ActionResult View(int id)
{
    Ballpark park = ballparkService.GetBallpark(id);
    if (park == null)
                return RedirectToAction("index");
    BallparkControllerViewData viewData = new BallparkControllerViewData {Ballpark = park};
    
    return RenderView("view", viewData);
}

In my code above, I'm calling my ballpark service to get the ballpark based on the id and then returning what it found. If it's null, I'm redirecting the user to the index action. If it's not null, I'm setting up my viewdata and then displaying the view. Pretty simple.

Now, here's a test that will fail:

[Fact]
public void Unknown_Ballpark_Should_Redirect_User_To_Index()
{
    var ballparkServiceMock = new Mock<IBallparkService>();
    ballparkServiceMock.Expect(x => x.GetBallpark(It.IsAny<int>())).Returns(new Ballpark());
    BallparkController controller = new BallparkController(ballparkServiceMock.Object);
 
    var result = controller.View(1) as ActionRedirectResult;
    result.ShouldNotBeNull();
    result.Values["action"].ShouldEqual("index");
    ballparkServiceMock.VerifyAll();
}

First, what is going on? Using Moq, we're creating a mocked instance of our ballpark service in the first line of the method.

Why are we mocking this? Since our ballpark service will eventually communicate with some data source, we don't want to have our controller unit tests depend on an external data source. For one, this will increase the testing time. If we have to wait for the database every time we want to run our unit tests, this will dramatically increase the amount of time it takes the runner to step through the tests. Second, it's not very dependable. If we created this test on Monday and used ID 45 because there was no such ballpark with an ID of 45 at the time, the test would work. However, if another developer creates a new ballpark that has an ID of 45 later in the week, the test will now fail. Of course, we could always clean up the data before we execute the test, but that leads me to my next point. Finally, we just don't care. We're testing the controller and how it works, not if the database is working. If we test too many things at once, our tests become fragile and brittle. We want to make sure the controller lives up to it's expectations. In order to accomplish this, we want to control what data is returned. For this reason, we're going to mock our service.

In the second line, we're setting our expectations. We're saying to the mocking framework: For this mock, we have a method called GetBallpark. We expect it to be called. We don't care what integer it passes in (It.IsAny<int>()). We just want to know if it was called. And if it is called, we want you to return what we tell you. In our expectation, we're returning a new instance of a ballpark. When the controller calls the service's GetBallpark method, it will return the new instance. 

Now, we're done setting up our expectations. The action is pretty dumb so we don't expect much from it. Next, we're going to call our action, pass in some random integer and get the result. Since the code should redirect the user, we should expect it to return an instance of ActionRedirectResult. Since we're casting using the as keyword, it will just set the result variable to null if it cannot cast it.

All we have to do now is run our assertions to see if what we expected to happen actually happened.

In this example our test failed. But why? Well, we expected our controller to redirect the user to an action since the ballpark was null. But wait, our ballpark wasn't null. The ballpark service actually returned an instance of a ballpark because we told it to. Because of this, an ActionRedirectResult was not returned. Instead, a RenderViewResult was returned which caused our cast to fail. Our result variable is now null, which caused the first assert to fail (result.ShouldNotBeNull()).

Fixing this should be pretty easy; we just need to remove the return value in our expectations.

[Fact]
public void Unknown_Ballpark_Should_Redirect_User_To_Index()
{
    var ballparkServiceMock = new Mock<IBallparkService>();
    ballparkServiceMock.Expect(x => x.GetBallpark(It.IsAny<int>()));
    BallparkController controller = new BallparkController(ballparkServiceMock.Object);
 
    var result = controller.View(1) as ActionRedirectResult;
    result.ShouldNotBeNull();
    result.Values["action"].ShouldEqual("index");
    ballparkServiceMock.VerifyAll();
}

Now, that test works. All we did was remove the return specification from the expect call. Why did that work?

Mocks - Loose and Strict

By default, when you create a mock without specifying a Moq "mockbehavior", it will create a loose mock, instead of a strict mock. A loose mock can be your friend, but it also can be your enemy. When you use a loose mock, the mocking framework will allow calls to everything, even if you didn't tell the mock to expect it or give it a return value. Since you didn't give it a return value, Moq (and Rhino Mocks) will just return that type's default value. In this case, it will return null for the method. In this example, that's good for us since our test wants GetBallpark to return null. If we had a strict mock, on the other hand, our test would fail because we didn't setup the return result.

The Rest of the Assertions

Since our last test code worked, it went through all of the assertions and passed. Our result variable wasn't null anymore, since our controller did redirect. Our result values collection contained a key called "action" with the value "index" as it redirected the user to the index action. And finally we verified that all mocking expectations have been met. In this case, they have.

xUnit.net Extension Methods

You may have noticed that our assertions didn't actually say "Assert" this and "Assert" that. Instead, our assertion methods were called from the variable we were asserting. xUnit.net has several extension methods that created this behavior. In order to add these methods, you must reference the xunit.net 3.5 extension method DLL that's located in the package.

Closing Up

I'll post a few more mocking examples shortly. I'll also post examples on MonoRail controller mocking.


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

ASP.NET MVC: Testing Controllers Using the Pre-Preview 3 Drop

April 22, 2008 06:49 by sbauer

A week or so ago, I wrote an entry about controller testing with the ControllerBuilder. In it I mentioned the "solution" obviously wasn't the best, and hoped that the work-around we were using wouldn't be needed for much longer. Well, last Wednesday the MVC team published a preview of preview 3. There were a number of changes included in this build, but I'm going to talk about controller testing improvements.

What We Did Way Back Last Week

Last week, we used a test helper from the MvcContrib project. Basically, the controller builder constructed an instance of our controller using Dynamic Proxy and then implemented an interceptor so it could grab data that we could use in our tests. It is quite a bit of work for something so straightforward. All we wanted to do was execute our action and see if it rendered the correct view.

What's My ActionResult?

If you remember, our controller actions are nothing more than public methods on a controller class. When you call the action from your browser, the ASP.NET MVC simply wires up a request that eventually executes the specified method. Nothing too crazy. The methods didn't even return anything; they were simply declared void.

Since we're working with preview releases here, you can't really expect things not to change. With the latest build, controller methods/actions now return an instance of ActionResult. What is ActionResult? ActionResult is an abstract class that is used to return the result of the action. A result can be a rendered view, a redirect to an action, or even a regular HTTP redirect to another location entirely. 

Getting the Result

Now, here's where you may notice the difference. In our previous controller code, if we wanted to redirect to an action, we could just call RedirectToAction in the middle of the action code and be done with it. RedirectToAction, and the other helper methods, all return instances of some form of ActionResult. RedirectToAction now returns ActionRedirectResult. RenderView returns RenderViewResult. What does this mean? When you call the helper methods, you need return their result now. Here's an example:

public ActionResult Index()
{
    return RenderView("index");
}

As you can see, you just need to ensure you return the result. This result is then used by the framework and you can also use it for testing. The code below illustrates a very simple test using the new build.

[Test]
public void BookController_Ensure_Index_Action_Renders_Index_View()
{
    BookController controller = new BookController();
    var result = controller.Index() as RenderViewResult;
    Assert.IsNotNull(result);
    Assert.AreEqual("index", result.ViewName);
}

I'll have more on this subject, and a real world example that puts them all together in a little while.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.NET MVC
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Using MvcContrib's TestControllerBuilder to Test Your ASP.NET MVC Controllers

April 14, 2008 06:40 by sbauer

One benefit of ASP.NET MVC (or any MVC framework) is the ability to test your code without having to start up a web server. Sure, you could have always unit tested your model layer, but what if you wanted to ensure that your web application code was interacting correctly with your domain?

A Quick Scenario

Lets say, for example, you have an Article controller. The controller has an action called "view". This action accepts one parameter, an integer, representing the article ID. The action code would then take the ID, and query the database for the article record. What happens if it doesn't find a record? Obviously, you could do any number of things. You could redirect them to a not found action or just display a different view. To keep things simple in this example, we'll just redirect the user to the main article page.

Controllers are Test-Friendly, kind of

As I said above, a benefit of the MVC framework is the ability to test your code without having to bother with ugly hacks to manipulate a web server and/or the ASP.NET pipeline. The ASP.NET MVC is an improvement in this area without a doubt. However, it's not perfect. There are areas in which you cannot test easily. RedirectData, for example, is one example of something that's difficult to test. There are ways to work around this limitation, but they are exactly that: a work-around. Fortunately, the MVC team has recognized a few areas that could be improved and are actively addressing our concerns for the next preview. 

Introducing the TestControllerBuilder

The MvcContrib project is an open source project that boasts quite a few additional features you can add to your project. For example, MvcContrib offers a variety of controller factories that integrate will all of the major IoC containers. In addition, MvcContrib also has a collection of view engines you can use if you're not satisfied with the WebForms view engine that's enabled by default.

The TestControllerBuilder is another contribution that's also available in this project. TestControllerBuilder uses a dynamic proxy and an interceptor to relieve some of the pain behind controller testing. Below is a sample test using the TestControllerBuilder, Rhino Mocks and MbUnit. In order for this to work, I need to make sure my mock instance of IArticleService returns a null instance. I'm using Rhino Mocks "SetupResult" for this.

 

[Test]
public void Unknown_Article_Redirects_To_Index()
{
TestControllerBuilder builder = new TestControllerBuilder();
ArticleController controller = builder.CreateController<ArticleController>(new object[] { articleService });
SetupResult.For(articleService.GetArticle(1)).IgnoreArguments().Return(null);
controller.View(1);
Assert.AreEqual(builder.RedirectToActionData.ActionName, "index");
}

 

Now, here's the action implementation.

public void View(int id)
{
    Article article = articleService.GetArticle(id);
    if (article == null)
        RedirectToAction("index");
    ArticleControllerViewData viewData = new ArticleControllerViewData {Article = article};         
    RenderView("view", viewData);
}
 

Changes are Coming

As I mentioned above, changes are coming. I'm not sure how long this code will be appropriate (hopefully not long). Either way, I thought it was worth mentioning. 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.NET MVC
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

CMAP Code Camp Spring 2008

April 13, 2008 09:21 by sbauer

I went to the Spring 2008 CMAP Code Camp yesterday with a friend and former co-worker yesterday. A lot of good sessions all around.

 A Gentle Introduction to Mocking -  Scott Allen discussed the basics of mocking with Rhino Mocks. Later, he switched it up for a test and used Moq. Pretty interesting stuff. Nothing completely mind blowing, but it was a little different. He also used xUnit.net as the unit testing framework. That was the first time that I had a good look at xUnit.net and Moq. Thanks Scott.

C# 3.0 New Features - Kevin Jones discussed all of the new features of C# 3.0. Lambda expressions, anonymous types, LINQ and everything else. Thanks Kevin.

 Decouple Your Applications with Dependency Injection and IoC Containers - Matthew Podwysocki discussed quite a few different things related to dependency injection and IoC Containers. He also gave a few demos using Windsor as well as Unity. Thanks Matthew

 Create AJAX Applications Using JQuery and ASP.NET MVC - Emad Ibrahim had a session on ASP.NET MVC and jQuery. He gave a good overview of a few ASP.NET MVC features and dove into jQuery. Given the short amount of time, he was able to show a few of jQuery's powerful features and even demo a site that he's created using both, Yonkly. Thanks Emad.

 Free sessions, free food, free prizes. You really can't beat it. Thanks to the CMAP group and the volunteers.

My goal is to blog about a these few areas shortly.

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

New Blog, New Start

April 13, 2008 09:19 by sbauer
I setup a new blog. I wasn't happy with my previous blogging software. With this change I hope to become much more active. I'm still thinking about a few topics, but I will generally stay around the .NET, ASP.NET, Web and Software Development genre.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories:
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

ASP.NET: Web Controls have an ID, a ClientID and a UniqueID. What's the deal?

November 8, 2006 11:05 by sbauer

While working on your ASP.NET page, you may have noticed that all of your web controls contain three different ID properties. That's great. But why? Uniqueness.

Lets say, for example, you have a Repeater control. In this Repeater control, you have an itemtemplate that contains a textbox and a label. Your label is called "ProductName" and your textbox is called "ProductQuantity". If your repeater contained more than one item, you would run into issues with html elements being named the same. That's a huge problem.

UniqueID fixes this issue. When the control gets created, a uniqueId is generated based on the control's heirarchy. For example, a textbox within a CreateUserWizard would have a UniqueID similar to "CreateUserWizard1$CreateUserStepContainer$Email". The UniqueID, as you can see, is a large string seperating the control's parents by a dollar sign. Pretty simple.

However, that's not technically valid in the HTML world. ClientID fixes this problem. ClientID replaces the invalid separator with a valid separator, like an underscore. Therefore, the textbox within the CreateUserWizard would have a ClientID similar to "CreateUserWizard1_CreateUserStepContainer_Email". As a result, when your textbox is rendered as a standard input element, the ID field would contain the value in the ClientID property.

If you want to access your control via javascript, don't use the ID property, and don't use the UniqueID property. Use the ClientID Property.

ConfirmButton.Attributes.Add("OnClick","javascript: alert('The username textbox as a value of " + Username.ClientID + "')";


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed