To Test Or Not To Test

Overview

I’ve never worked for a company that has required unit tests to be maintained for a project. The places that I’ve worked have certainly encouraged me to test my code. However, I don’t know if they have really bought into the idea that you should spend the time to establish unit tests up front and maintain them as you make changes to the project. Perhaps at least partially as a result of this, my personal projects also do not have well maintained unit tests.

When you create a new ASP.NET MVC project in Visual Studio, you are prompted regarding whether or not you would like to create a test project. This is a great encourager to get folks started down the road of planning out unit tests from the beginning. Unfortunately, I have ignored that prompt each and every time that I started out a new MVC project. However, this week, I thought that I would take a look at what it would take to add unit tests to one of my existing projects. I figured what better way to do this than to add them to the MovieApp project that I talked about in a previous article.

Adding Tests

Adding tests to an existing MVC project is quite easy. All that you need to do is to right-click on existing controller method (for example) and select “Create Unit Tests”. When you do this, Visual Studio will prompt you for some additional parameters.

You can select what project your test will be added to. It can be an existing project, or Visual Studio can create an entirely new test project for you. This is great when you are wanting to add tests to an old project. Visual Studio does a lot of the grunt work needed to get you started. In fact, if you go with the defaults and click OK for the first test that you try to create, Visual Studio will create a new testing project for you that includes a new class corresponding to your controller and a new method corresponding to the controller method that you asked to create the test for.

Once you start adding tests, you will probably want to configure Visual Studio to run them every time that you build. Fortunately this is easy as well. All that you have to do is click on the Test menu, select Test Settings, and finally select Run Tests After Build. This helps you to get immediate feedback regarding how code updates impact your existing tests.

Although automatically running unit tests is easy, I would like to see a failed test result be more obvious. From what I can see, it looks like you need to open up Test Explorer to see that result. I would prefer for Visual Studio to prompt you with a notification for a failed test and/or stop you from debugging until you fix the test. At least I would like for this behavior to be an option. I can understand how it would be annoying for some users.

Mocking Up Objects

A given controller method will likely need access a number of different objects. You may not want to instantiate a full version of this object within your test method. If not, you will be using what is know as a mock. For example, take a look at the following controller method, which returns a list of movies.

This method is quite simple, but it does require the use of a movies database repository (the _repo variable). If we are focused on testing the controller method itself, we will want to leave the database out of the picture. We don’t want our test method to fail just because the database is inaccessible. As a result, we would want to mock up our database repository.

There are a number of mocking frameworks available for .NET, but one of the most popular is Moq. I have worked with this one a bit in the past, so I decided to give it a shot once again. To include Moq in your project, you will want to add the latest Moq NuGet package to your test project.

Example Test

While researching this article, I ran across DanylkoWeb’s Ultimate Guide to Unit Testing in ASP.NET MVC. I found it to be quite informative, and it served as an inspiration for the example unit test that I am providing here. If you would like to see a more thorough coverage of MVC unit testing, that is a great place to start.

Below is my example unit test for the previously discussed Index controller method. In this example, I am mocking up my movies database repository. Here I provide some example data, and then setup a placeholder GetAll method that will be called from my Index controller method. The Mock<IMoviesRepository> object that I create is done using the Moq mocking framework.

At the tail end of the test method, we perform two assertions that determine whether or not the test fails. First, we check that the result is not null. We should have received a result from the Index method. Next, we confirm that three movies are available in our list of movies, which correspond with the three movies at the top of our code example. If either of these assertions fail, the test will fail.

Example Project

At the end of this article, I will provide an updated version of the MovieApp solution that includes a test project. In there, you will find tests for each of the methods in the Home controller. Some of these tests are quite simplistic. Obviously, the whole web application is quite simplistic, so this probably makes sense.

One way that the tests could be further extended would be to add checking for invalid movies in the tests for the Create and Edit methods. To do this, we might want to create a movie view model that uses data annotations to put restrictions on the movie properties, such as being a required field or allowing a certain maximum number of characters. After doing this, we could test for each of the restrictions that we have put into place.

Conclusion

While researching this article, I found the best sales pitch I have ever heard for why you should invest time in maintaining a standard set of unit tests. In a recent post, K. Scott Allen said that unit testing taught him everything that he knows. He argues that unit testing will force you to learn such tough topics as how to properly apply design patterns and decompose classes. The reasoning is that a poorly architected class will be much more difficult to test. His argument has encouraged me to spend more time on unit tests, as I believe that I have a lot to gain by putting them to use. Thankfully, Visual Studio makes it easy to get started, and I hope that this article will help you as you start down the road to unit testing success.

Attracting More Users With External Logins

Overview

ASP.NET MVC makes it easy to implement external logins. This week, I took some time to experiment with the external logins feature that is provided with the default MVC templates in Visual Studio, and I found it to be a mostly simple feature to setup. Microsoft has even done a good job of providing some example articles on how to set this feature up, which proved to be quite helpful for me.

What are external logins? When you setup an MVC project with individual account authentication, users can sign up for an account using credentials that are specific to your web application. Using a unique set of credentials for each web application can quickly get old for users. As a result, you probably have seen that many sites will offer the option to used to leverage existing accounts from other services. This is what Microsoft refers to as an external login. Common examples of external logins that you may see on other sites include Google, Facebook, and Twitter.

Default Example

The most helpful setup example that I found to get started with external logins was Microsoft’s own example with Facebook and Google. I was able to follow through their Google example using Visual Studio 2015 and MVC 5. I did run into one small issue, but it was easily resolved. When I mistakenly skipped over the step to enable the Google+ API, I was presented with an access denied error.

If you read the previously mentioned article, you will see that there are two primary steps to setting up an external login. First, you configure support for your application with the login provider. Second, you configure code in your application to communicate with the external login.

Configuring the application code should be particularly easy for the four providers that are referenced in the default Startup.Auth.cs code that is provided in the MVC template for Visual Studio 2015. These include Microsoft, Twitter, Facebook, and Google. Indeed, updating the code for Google proved to be a cakewalk. All that I had to do was to uncomment the Google specific block of code in Startup.Auth.cs and provide the client ID and client secret provided by google. Below is an example with dummy values.

 

Add-On Example

If you do a little bit of research, you will find that there is an OWIN OAuth Providers project that provides support for more than 40 external login providers. Taking advantage of this project, really opens up a lot of possibilities to you. To take advantage of this project, you simply need to add a reference to the Owin.Security.Providers NuGet package. If you don’t want to include support for all of the, you can reference a package that supports an individual login such as Owin.Security.Providers.Wordpress.

I gave the previously mentioned WordPress NuGet package and encountered very little difficulty in getting this running. In order to register your application with WordPress, you need to go to the WordPress applications page. Setting up an application there is very similar to the steps described in the Microsoft article for Google and Facebook. You will need to provide a redirect URL such as https://localhost:44300/signin-wordpress, that ends with signin-wordpress.

After setting up the application with WordPress, you will be given a client id and client secret to use in your application code. After referencing the Owin.Security.Providers.Wordpress NuGet package, you will want to reference that package (add a using statement) in your Startup.Auth.cs and add a code block at the end of the ConfigureAuth method that looks like the example below.

After doing this, you will see a new WordPress button on your application’s login page. Clicking the button should prompt your for WordPress credentials before logging you in to your web application.

Error Feedback

During my testing, one shortcoming that I saw in the handling of external logins was the fact that no feedback is reported to the user when the external login fails. Instead, the user is simply taken back to the login page without any indicator of a failure. I didn’t feel like this would be a good way to handle a failure in the real world, so I added a simple error indicator so that the user would be aware of the failure.

In order to implement this, I had to first pass an error message to the Login action on the Account controller. I did this in the first block of code within the ExternalLoginCallback method. Below is the modified code example, and you can see that I am providing a new errorMessage parameter.

Next, I had to add the errorMessage parameter to the Login get method on the Account controller. I also had to set a new ErrorMessage property on the ViewBag so that I would be able to pass it to the view. Below is the modified Login method.

Finally, I had to output the error message in _ExternalLoginsListPartial.cshtml when appropriate. I added an if statement to this view so that the message would only appear when an error was present. Below is the relevant portion of the view that was modified.

Surprising Struggles

One annoyance that I had with external logins was that I was not able to get the Microsoft external login to work appropriately. I could not find an MVC 5 specific article for the Microsoft login, but I did find this ASP.NET Core article. I followed the steps there to register my application with Microsoft. I then followed steps similar to those outlined in the Google article to configure my application. After doing this, and even after much research into the matter, I am still getting an access denied error. I’ve even posted this question to Stack Overflow, which does not currently have any answers. Although I will readily admit that the issue is likely somewhere on my end, I find that it is odd that it’s more difficult to setup a Microsoft external login than a Google external login, considering that MVC is a Microsoft framework.

Final Thoughts

Aside from the difficulties that I had with Microsoft accounts, configuring external logins for an MVC web application project proved to be quite painless. I was able to quickly add a couple of these external logins to a production application, and I look forward to leveraging this feature again in the future. I know that I will think twice about signing up for a web app that does not provide such external logins, so hopefully this feature will prove to be of benefits to the users of my web apps in the future.

Heading Down Easy Street With HTML Helpers

When ASP.NET MVC was unveiled, it came with some helper methods that can make repetitive HTML generation tasks a breeze. These helpers exist in the System.Web.Mvc namespace. You see they helpers used often with Razor, but they can be used with any view engine. For an example of their usage with another view engine, take a look at my previous article about using the Spark view engine.

The most common task achieved with the HTML helper methods is to generate an input element. There are a variety of helpers for specific inputs. For example, one can generate a textbox for a property on a given view’s model. Each one of these input specific helpers has a loosely typed and strongly typed version.

Below is an example of the loosely typed helper method for a textbox. The initial parameter is a string that corresponds with a property name on the view’s model. The second parameter is a value for the textbox, and the value of the model property will be used, since null was specified. Finally, the third parameter allows one to specify attributes on the element that will be generated.

The next example shows the strongly typed helper method for a textbox. Notice that the first parameter is a lambda expression that specifies a property on the view’s model. No value parameter is specified in this example, as it is automatically pulled from the model’s property.

The HTML helper methods also include templated helpers, such as editor and editorfor. These helpers will pick the appropriate HTML markup for a given property. In addition, you can influence them by using the DataType attribute, which is found in the System.ComponentModel.DataAnnotations namespace.

Below is an example of setting up a property on a view model so that it can be output as a multiline textbox when combined with templated helpers. Using this class of attributes, you can influence the rendering of your properties in a number of ways.

Here is the corresponding templated helper being used in an editor view for the same view model.

As if those features weren’t enough, you can also extend the HTML class with your own custom helpers. All that you need to do is to add a new static class to your project with one or more static extension methods. This is a very powerful feature and can be leveraged to achieve even greater streamlining of markup generation and reduction in code duplication.

Below is an example of a custom helper that is used to generate HTML 5 figure markup. Note that the extension method can take multiple parameters and apply them to the generated markup. In this case, the extension method takes an image URL and a caption describing the image.

The custom helper method could be called in the corresponding view using the following syntax.

HTML 5 offers a number of new markup options that you could leverage within custom HTML helpers. If you’d like to learn more about HTML 5, I recommend that you read Training Guide Programming in HTML5 with JavaScript and CSS3 (MCSD): 70-480 (Microsoft Press Training Guide). I found it to be quite helpful in bringing me up to speed on new HTML 5 features and functionality, particularly in terms of providing practical exercises.

HTML helper methods have proven to be one of many great additions that were included with the roll out of ASP.NET MVC. Using the helpers is certainly easier than constantly writing out all of one’s HTML markup by hand. The fact that you can customize the output of the helper methods with templated helpers makes this feature even better. Finally, being able to create your own custom helper methods makes HTML helpers hard to beat. If you’re not already taking advantage of them, regardless of the view engine that you’re using, get started today!

ASP.NET Remember Me Functionality

I deployed a new ASP.NET web application a couple of months back. When I set it up in Visual Studio, I used the individual user accounts option for authentication. The login screen that is included in the generated project includes a “Remember Me” checkbox. I would typically use the application once per day, but I noticed that even though I checked the “Remember Me” checkbox, my credentials would be forgotten the next day.

Heading in, I did not know much of anything about how the various ASP.NET MVC authentication options worked. It turns out the the individual user accounts option results in ASP.NET Identity being used. ASP.NET Identity makes use of OWIN. This option is not the same as Forms Authentication, which is an older technology. I assumed that was what was actually being used, so this was a surprise to me.

After doing some research on my issue, I discovered that the default timeout for ASP.NET Identity with the “Remember Me” option was 14 days. Once I dug deeper, I found that I had a .AspNet.ApplicationCookie cookie with an expiration date that was set 14 days out. However, even with that cookie, my browser would seem to forget the login.

How should “Remember Me” work? If you login without “Remember Me” checked, close your browser, and reopen your browser, it will forget you. If you login with “Remember Me” checked, close your browser, and reopen your browser, it will remember you. The problem for me was occurring if I would leave the browser closed for more than 20 minutes.

During my research, I read that several issues had been fixed in ASP.NET Identity 2.2. I was using 2.1, so I tried upgrading. Unfortunately, that also did not make a difference. At least having the newer version did not result in any additional negative impacts for me.

I did some testing locally, and I noticed that the behavior was different. The browser would still remember me after the 20 minute timeframe had passed. This definitely made me curious regarding whether there was something in the hosting environment that was causing me problems. I did compare the web.config file for both environments and found no relevant differences.

After running through a number of test scenarios, I decided to post a question to Stack Overflow. Someone there mentioned that it may be related to the application pool idle timeout. I am the only person currently using the application, so it is very susceptible to idle timeouts. After consulting with my hosting provider, I found that they do not allow that setting to be modified. Instead, I ended up setting up a scheduled task with the hosting provider to ping the web site and keep the activity going. After that, I was finally seeing the browser maintain my credentials after the 20 minute time period.

Admittedly, this was not the solution that I would have hoped for. If I ever move hosting providers, I will need to setup a similar solution there. However, it was beneficial for me to have the problem, as it afforded me to learn a little bit about how the default ASP.NET MVC authentication setup works. I’m looking forward to digging into it further in the future.

Spark View Engine

This week I am continuing my exploration of view engines by taking a closer look at the Spark view engine. I wanted to find at least one third party view engine that I could play around with and Spark seemed like potentially the best candidate. Spark was released before Razor, and it appears that it was last updated in June 2015. The good news is that there is a NuGet Package that allows you to use Spark with MVC 5. This helps to make it at least usable with current versions of Visual Studio.

One of the primary goals with Spark is that HTML comes to the forefront in the markup with less intermixed code than was seen with the ASPX view engine. Part of the driving force behind this implementation was that ASPX pages would be more and more difficult to maintain and read as time went by and they grew in size. The view engine was authored by Louis Dejardin and based on comments and search results, I’m going to guess that it was at one time the most popular third party view engine.

In my most recent post, I mentioned refreshing a classic ASP.NET tutorial web application, the Movie App. I had brought this project up to speed using MVC 5, so that I could use it as a basis for other experiments. I figured that a perfect usage for this would be to convert my previously created version of the Movie App to leverage the Spark view engine.

Getting up and running with Spark was not too tough. I started out by referencing the previously mentioned Spark.Web.Mvc5 NuGet package. After that, I updated my Global.asax.cs, removing all other view engines from usage and adding the Spark view engine. This would be the approach that you would want to take if you were wanting to using only Spark. If you wanted to also use Razor or ASPX, you would not bother to clear out the existing view engines.

As an optional step, you can add a spark section to your Web.config. Take a look at the configuration documentation for more details on what you can do there. I did read that setting the debug setting to true can be helpful in troubleshooting view compilation errors, so you may want to consider using that setting.

After modifying the configuration, I needed to make a few changes to the file structure under the Views folder. First, I had to rename all the views to *.spark, so that they would be recognized by the Spark view engine. Second, I deleted _ViewStart.cshtml, as it is not used by Spark. Third, I renamed _Layout.cshtml to Application.spark. Spark automatically looks for a layout file by that name. Finally, I had to add a reference to System.Web.Optimization in the _global.spark file that was added when I referenced the NuGet package. This enabled me to reference Styles.Render and Scripts.Render.

The next step, and the most involved step, was to replace the existing Razor syntax in all of the views with Spark syntax. One of the things that pops out at you right away is that several of the C# constructs, such as if and for are replaced by markup that looks like HTML. This does contribute to the readability of the document. Below is one example of a view that I updated, the movie creation view.

The Form tag in the above example leverages another important feature of Spark, bindings. You can create a binding that will replace HTML-like markup with C# code. In this case, I created a binding that could wrap some HTML with the appropriate code needed to render a form. This binding is defined within Bindings.xml, which sits in the Views folder. Below is the example binding that I created.

After setting up the binding and replacing the existing Razor syntax in the views, I was pretty much set to go. With a minimal amount of effort, I once again had the Movie App running, but this time using Spark syntax. Despite the fact that Spark hasn’t been updated in several years, it is still a fairly painless experience to get started.

Would I choose to use Spark over Razor? Probably not. I’ve already got some amount of Razor experience and I didn’t see anything compelling enough to persuade me to change. However, it is nice to know that you have options, and I can see how Spark was an attractive alternative to ASPX. The HTML-like markup does make it easier to read than a complex ASPX view.