Get Started with Angular 2 and ASP.NET Core in Visual Studio Code

Getting off the ground with Angular 2 and ASP.NET Core right now can be a little intimidating. There's multiple ways to combine these two powerful frameworks to make something awesome. The goal of today's post is to clear up some of the confusion by showing you a sane, cross-platform approach to getting an Angular 2/ASP.NET Core app started using Visual Studio Code, .NET Core CLI and angular-cli.


Dev environment

I'm using Windows 10 with the latest versions of:

  • Visual Studio Code - v1.11.1
  • .NET Core SDK v1.0.1 dotnet --version
  • node v6.10.0 node -v
  • npm v3.10.10 npm -v

Finally, I had to install the C# for Visual Studio Code extension.

Angular CLI

Angular 2 comes with an awesome new tool in angular-cli that can create your project, add files, and perform a number of other development tasks such as testing, bundling, and deployment. It is the new swiss army knife of angular development.

To get started make sure you're running Node 6.9.0 or higher and NPM 3 or higher. From a command prompt install it using npm.

npm install -g @angular/cli

Next, we'll create a new project using ng new. This command creates a new folder for the project using our app name DotNetGigs. The --style argument tells the generator we want the app to pre-compile our css using sass with scss syntax. The documentation contains all the commands and switches available for working with angular-cli. I highly recommend you check it out.

ng new DotNetGigs --style=scss

After the generator creates the app you can open it from the command line by launching Visual Studio Code directly from the project folder.

cd dotnetgigs
code .

Adding Bootstrap

The app template generated by the CLI has no styling so I'd like to jazz things up a bit with bootstrap. Back at the command prompt I use npm to install Bootstrap 4 alpha in the app directory:

npm install bootstrap@next --save

Then I modified the .angular.cli.json file to add the required script files to the scripts array.

"scripts": [
  "../node_modules/jquery/dist/jquery.js",
  "../node_modules/tether/dist/js/tether.js",
  "../node_modules/bootstrap/dist/js/bootstrap.js"
],

Finally, I added the bootstrap css to the styles array.

"styles": [
  "../node_modules/bootstrap/dist/css/bootstrap.css",
  "styles.scss"
],

A new component

I want to build out the layout of the UI a bit by adding a new component. Using the CLI I generate a new header component within the app folder.

cd src/app
ng generate component header

The command created a new folder and associated files for the html, css, test and class code. It also updated our app.module so other components will be aware of it. Notice the same naming convention is used as in the rest of the app. Using the CLI provides a consistent and modular approach to extending our application following baked-in best practices and patterns. This is one of its biggest benefits.

Next I'll add the bootstrap navbar markup to the header.component.html file.

<nav class="navbar navbar-toggleable-md navbar-inverse fixed-top bg-inverse">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
  <span class="navbar-toggler-icon"></span>
  </button>
  <a class="navbar-brand" href="#">dotnetGigs</a>
  <div class="collapse navbar-collapse" id="navbarCollapse">
  <ul class="navbar-nav mr-auto">
  <li class="nav-item active">
  <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
  </li>
  <li class="nav-item">
  <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
  <a class="nav-link disabled" href="#">Disabled</a>
  </li>
  </ul>
  <form class="form-inline mt-2 mt-md-0">
  <input class="form-control mr-sm-2" type="text" placeholder="Search">
  <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
  </form>
  </div>
  </nav>

And finally, add the new header component to the main app.component.html template.

<!-- app.component.html -->
<app-header></app-header>

<!-- container -->
<div class="container-fluid">
	<!-- Begin page content -->
	<p>Content here!</p>
</div>
<!-- /container -->

With everything in place, I'm ready to smoke test my app to see how things look. Back on the command line I issue a simple ng serve to build and fire up the app on the node dev server @ http://localhost:4200

Voila our angular app with bootstrap navbar is working!


ASP.NET Core backend

Time to build our backend. To get started in the root project folder I ran the dotnet CLI command to generate a new, empty ASP.NET Core application.

dotnet new web

This command generates a few files necessary to get a bare-minimum ASP.NET Core server on its feet: Program.cs, Startup.cs and dotnetGigs.csproj.

Note: when opening one of *.cs files for the first time in Visual Studio Code you'll be prompted to restore packages required by the project so be sure to accept those requests.

Now we need to use the CLI to add static file support to serve the index.htm, css, images and javascript files required by our SPA.

dotnet add package microsoft.aspnetcore.staticfiles

After executing this, you'll likely see another "unresolved dependencies" message in Visual Studio Code. Simply choose to restore the package.

With the package added, we just need a small change in Startup.cs to add static file support in the middleware.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  loggerFactory.AddConsole();

  if (env.IsDevelopment())
  {
  app.UseDeveloperExceptionPage();
  }

  app.UseDefaultFiles();
  app.UseStaticFiles();
}

Trigger the Angular build from ASP.NET Core

Add a build step in the .csproj file to run the angular-cli build command after our ASP.NET Core project builds.

<Target Name="AngularBuild" AfterTargets="Build">
  <Exec Command="npm run build" />
</Target>

Serve the Angular app from ASP.NET Core

Finally, we need to let Angular know that its build output should go to the wwwroot folder of our server. In the .angular.cli.json file simply change the "outDir" to "wwwroot":

{
      "root": "src",
      "outDir": "wwwroot",
      "assets": [
      ...

Run it!

Hit F5 in Visual Studio Code to launch the debugger. Your Angular app should now be hosted by ASP.NET Core and running on port 5000 instead of 4200 which is the angular-cli default - sweet! 🙂

Wrapping up

Properly integrating Angular client-side code with server-side code can be complicated and time-consuming. But by using the new CLI tools with just a few simple config changes we're able to very quickly create a solid foundation for an Angular 2/ASP.NET Core solution managed entirely by Visual Studio Code.

If you have a question or are building something cool using this approach please let me know in the comments below.

Thanks for reading!

Source code

Beginning Test-Driven Development in .NET Core

My previous two posts focused on making better software in asp.net core by applying dependency injection and unit testing to our software design. Today, we'll extend that theme by looking at test-driven development in .NET Core. My goal is to show you how it can be used to create better applications and improve your productivity as a developer - sound good?


What is test-driven development?

TDD is not a specific framework or technology - it is an approach. It's a thought process where we think of testing our code from a different perspective by writing the test code first before a single line of related functional code exists!

In a typical scenario, you first write some code, then write some tests - rinse and repeat. In TDD, you write the test case before you write a single line of code. Naturally, the test fails. Next, you write just enough code to satisfy the test so it passes. After that, we refactor as necessary to improve the design while ensuring that all tests still pass. This cycle is commonly known as Red, Green, Refactor.

TDD Cycle
You repeat this cycle many times. Typically, the initial cycles are very quick but gradually slow down as more time is spent refactoring.

Project setup

I'm using Visual Studio 2017 but will begin by setting up my project using and the new dotnet core tooling.

From the command line in my project folder, I first create a new solution file:

dotnet new sln -n dotnetCoreTDD

Next, I made a new console app project.

dotnet new console -n TDDDemoApp

Then, a new test project based on xUnit unit testing tool.

dotnet new xunit -n TDDDemoAppTests

Finally, I added both projects to my new solution.

dotnet sln dotnetCoreTDD.sln add tdddemoapp/tdddemoapp.csproj
dotnet sln dotnetCoreTDD.sln add tdddemoapptests/tdddemoapptests.csproj

TDD process in action

Opening the solution, I'm starting with a completely clean slate - an empty console and test project. Let's change that.

I'm thinking about a component for my program that can analyze a piece of text and return some useful information about it like the total word count, repeated words, maybe even more advanced things like grammar and spelling.

With a few requirements in mind for this new component, I jump straight to my test project and make a new class for its tests: TextAnalyzerUnitTests.cs

To begin, I'd like a function to simply return the total word count of a given piece of text. My first step is to write a test for it. Here's what I came up with:

The test case simply news up TextAnalyzer, calls the method and checks for the expected result. As I have not written a single line of code for TextAnalyzer yet, I can't run this test or even compile the project.

We are definitely in the red.

The next step is to create the TextAnalyzer component. To start, I created a new TextAnalyzer.cs class in the console project and added the minimal amount of code to get everything compiling successfully.

At this point, we don't care about the purity of our design or elegant code. We'll take care of that when we refactor. For now, GetTotalWordCount() only throws an exception but with this stubbed out everything compiles and I can at least run the test.

Our test fails as expected because we're just throwing an exception but we're ready to fix that now by refactoring GetTotalWordCount() with the necessary code to count the words in a given string.

public int GetTotalWordCount(string text)
{
  int wordCount = 0, index = 0;

  while (index < text.Length)
  {
  // check if current char is part of a word
  while (index < text.Length && !char.IsWhiteSpace(text[index]))
  index++;

  wordCount++;
 
  // skip whitespace until next word
  while (index < text.Length && char.IsWhiteSpace(text[index]))
  index++;
  }

  return wordCount;
}

With the method properly implemented, I rerun the test and success - a green check! The method is working correctly and returns the expected word count in the test case.

We've just created a test-driven class and method - sweet! This process is very iterative. So at this point, we might spend more time refactoring GetTotalWordCount() to improve its design by adding things like validation, error handling etc. or we might move on to our next requirement. Either way, we follow the same process of writing the failing test case first, adding a minimal amount of code to pass it, and finally an exercise of refactoring and testing to ensure everything still passes.

Benefits of TDD

  • Intentions are clear - We didn't write a line of code until we knew exactly what we wanted to do because we let our tests drive our code design. This results in no unnecessary code and a laser focused design.

  • You have to eat your own dog food - TDD forces you to write your tests as a consumer of your own code. This makes you continuously think about its API.

  • Iterative cycles - First we started with no code, then we added the bare minimum to get things compiling, finally we implemented the real functionality. We quickly did 3 iterations in this guide but in a real-world project, we'll perform many more iterative rounds of development and testing as our project evolves over time. The iterative process of TDD means we can react to new or changing requirements with confidence.

  • Defects are identified early - Testing early and often means many bugs will surface as soon as they're introduced. The earlier a bug is caught, the cheaper (in time and money) it is to fix.

  • Testing guaranteed - Despite our best intentions, we all know adequate unit testing just doesn't always happen. TDD forces us into the habit of writing unit tests for production code - no excuses.

Wrapping up

Applying TDD requires a fundamental change in how we think about writing code. So if you're planning to try it out on your next project (or within an existing one) be patient and approach it in baby steps. To get a feel for it, try and isolate a single class or component and apply the process of thinking through the design from a testing perspective. If you find yourself simultaneously changing the code and tests it's usually a sign of a misstep in your design - no big deal. Keep iterating and you'll get it. 🙂

Thanks for reading!

Source code

Learning Unit Testing in ASP.NET Core

This is the follow-up to my last post about IoC and dependency injection. Today, we'll be focusing on unit testing. Since DI and unit testing go hand in hand we had to cover those topics first to lay the foundation for what we'll learn today. If you're not already familiar with IoC/DI then I'd encourage you to go back and check out that post first before you dig into this one.


What is unit testing?

Unit testing simply verifies that individual units of code (mostly functions) work as expected. They allow you to isolate these specific methods/functions and test their behaviors under different conditions and data.

Why bother unit testing?

One big reason is that unit tests make it much easier to change our code while making sure we don't change its behavior (refactoring). This means that properly unit tested code can be heavily refactored/cleaned up so if we happen to break existing functionality we'll know instantly by way of failing tests. This is awesome because it means bugs can't sneak further into our app development. The earlier a bug is identified the less it costs to fix.

Unit tests create a better design

Unit tests help influence our software design by exposing natural decoupling points in our code. If something is awkward or impossible to test it's likely there are tightly coupled dependencies that are causing us grief. When you're designing classes with unit testing in mind you're forced to break your app down into separate, testable components.

Once you get a feel for this you'll never go back to your old process.

In some cases, you almost don't have to think about the design at all. The tests will guide you to ensure the right behavior lands in the right classes/methods and those classes are properly decoupled from each other using interfaces and dependency injection. This has an added side effect of creating focused components that follow the single responsibility principle.

What about test-driven development?

I typically write code in small increments in parallel with my tests and practice what I call test-driven thinking. Test-driven development (TDD) is a different process where tests are written before a line of code is cut - rad! The tests act as a spec whereby you write a test for a non-existent object/function and it initially fails because no code exists yet. Then you write just enough code to get it to pass.

So while TDD is often a motivation for unit testing, unit testing does not require TDD. I want to make that distinction as this can be a point of confusion for folks who are familiar with these terms but may not fully understand how they work together.

Adding a unit test project

A good approach to unit testing in .net is to add your tests in their own class library project completely separate from your application code. So, to get started I added a new .NET Core Class Library project to the existing solution we used in the first post.

Next up, we need to add a unit testing framework - we'll use xUnit as it currently supports .net core and works with the built-in visual studio 2015 test runner. NUnit is another very popular framework - there are differences between the two but neither will change your life for the better in any dramatic way so don't split hairs about which one to go with.

An additional library is required for mocking up some behavior and data within our unit tests. This can be referred to as mocking, stubbing or faking depending on who you talk to but let's not get caught up with semantics. We'll see in a minute how to use moq to mimic behavior of an interface in our test - this is a powerful construct in unit testing.

Finally, we need to add a reference in our unit test project to our application so we have access to the classes we want to test.

For completeness, your project.json should look like this:

{
  "version": "1.0.0-*",

  "dependencies": {
    "moq.netcore": "4.4.0-beta8",
    //http://stackoverflow.com/questions/37288385/moq-netcore-failing-for-net-core-rc2
    "System.Diagnostics.TraceSource": "4.0.0-rc2-24027",
    "NETStandard.Library": "1.6.0",
    "xunit": "2.2.0",
    "dotnet-test-xunit": "2.2.0-preview2-build1029",
    "ASPNetCoreDIAndUnitTesting": "1.0.0-*"
  },

  "testRunner": "xunit",

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [ "netcoreapp1.0", "portable-net45+win8", "dnxcore50" ],
      "dependencies": {
        "Microsoft.NETCore.App": {
          "version": "1.1.0",
          "type": "platform"
        }
      }
    }
  }
}

The important parts are "dependencies:{...}" which brings in the xUnit framework and it's test runner and "testRunner": "xunit" which instructs the dotnet cli we're using xUnit for our tests.

Writing unit tests

Ok, we covered off some good theory on what unit tests are and why we should use them. We got our project provisioned with the xUnit framework so our app code is testable. We're ready to a write a test...

Our first test will target the TeamStatCalculator class in our app. Specfically, the super-complex GetTotalGoalsForSeason() method.

public class TeamStatCalculator
{
  private readonly ITeamStatRepository _teamStatRepository;

  public TeamStatCalculator(ITeamStatRepository teamStatRepository)
  {
     _teamStatRepository = teamStatRepository;
  }

  public int GetTotalGoalsForSeason(int seasonId)
  {
    // get all the team stats for the given season
    var teamStatsBySeason = _teamStatRepository
    .FindAll(ts => ts.SeasonId == seasonId);

    // sum and return the total goals
    return teamStatsBySeason.Sum(ts => ts.GoalsFor);
  }
}

Breaking it down, we can see this method simply queries _teamStatRepository to get the list of team stats for a given season and then relies on linq's Sum() to return the total goals for all the elements...too easy.

One notable thing is that we can see _teamStatRepository is a dependency that gets injected through our constructor. In reality, this repository could be talking to a database, a file or rest api to get its data but the point is it doesn't matter because we've hidden its implementation details behind the ITeamStatRepository interface. We only deal with a contract of its behavior not the concrete details of the class. You'll see why this matters in a few seconds. Side note, if your test code writes to a file, opens a database connection or does something over the network, it's more appropriately categorized as an integration test - but that's a different topic.

Let's see the associated test for this method...

[Fact]
public void GetTotalGoalsForSeason_returns_expected_goal_count()
{
  // ARRANGE 
  var mockTeamStatRepo = new Mock();

  // setup a mock stat repo to return some fake data in our target method
  mockTeamStatRepo
 .Setup(mtsr => mtsr.FindAll(It.IsAny<Func<TeamStatSummary, bool>>()))
 .Returns(new List<TeamStatSummary>
     {
        new TeamStatSummary {SeasonId = 1,Team = "team 1",GoalsFor=1},
        new TeamStatSummary {SeasonId=1,Team = "team 2",GoalsFor=2},
        new TeamStatSummary {SeasonId = 1,Team = "team 3",GoalsFor=3}
     });

  // create our TeamStatCalculator by injecting our mock repository
  var teamStatCalculator = new TeamStatCalculator(mockTeamStatRepo.Object);

  // ACT - call our method under test
  var result = teamStatCalculator.GetTotalGoalsForSeason(1);
 
  // ASSERT - we got the result we expected - our fake data has 6 goals
  we should get this back from the method
  Assert.True(result==6);
}

Unit test structure

Our unit test follows the "AAA" approach where we:

  • Arrange by doing any necessary setup.
  • Act by executing the test - ie. calling the actual method/function and grab its result.
  • Assert by verifying the returned result matches expected results.

We can see the bulk of our test code happens in the arrangement part. Here we're creating a mock of our ITeamStatRepository and defining some custom behavior and data for its FindAll() method. We then inject our mock repo object into TeamStatCalculator when we create it.

Once our setup is complete, the act portion simply calls our target method GetTotalGoalsForSeason(1) to get a result. That's only one little line in our test but if you run the test while debugging you can see the real power and magic in all of this. If you actually step through GetTotalGoalsForSeason() you will see our mock repository object returning the data we made up in our test within our app code! This is IoC/DI in its full glory! We've completely inverted control of creating our repository and can make it do anything we please in our test - let that sink in! 🙂

Finally, in our assertion - we know we have 6 goals in our test data and thus our method should return that if it's working properly.

Running the test in VS test explorer I get a passing green check!

Alternatively, we can run tests from the command line using the new CLI tools. In our project directory simply run the command dotnet test to invoke the test runner from the command line.

Unit testing controllers

Controllers are a big part of an ASP.NET Core application so providing some coverage for them is important to ensure they behave as expected. We typically want our controllers to be thin and free of code directly performing any sort of business logic or data access (this stuff belongs in its own class(es)). So, we're really just verifying how our controller actions behave based on given inputs and the responses they generate based on the operation(s) they perform.

Let's write a test for the Index() method on the HomeController.

public IActionResult Index([FromServices] IGameRepository gameRepository)
{
  var model = new IndexViewModel
  {
    Players = _playerRepository.GetAll().ToList(), // constructor injected
    Games = gameRepository.GetTodaysGames().ToList() // parameter injected
  };

  return View(model);
}

The associated test for this action...

[Fact]
public void Index_returns_viewresult_with_list_of_players_and_games()
{
  // ARRANGE 
  var mockPlayerRepo = new Mock();
          
  mockPlayerRepo.Setup(mpr => mpr.GetAll()).Returns(new List
  {
     new Player {Name = "Sidney Crosby"},
     new Player {Name="Patrick Kane"}
  });

 var mockGameRepo = new Mock();

 mockGameRepo.Setup(mpr => mpr.GetTodaysGames()).Returns(new List
 {
   new Game {
            HomeTeam = "Montreal Canadiens",
            AwayTeam = "Toronto Maple Leafs",
            Date = DateTime.Today},
   new Game {
            HomeTeam = "Calgary Flames",
            AwayTeam = "Vancouver Canucks",
            Date = DateTime.Today},
   new Game {
            HomeTeam = "Los Angeles Kings",
            AwayTeam = "Anaheim Ducks",
            Date = DateTime.Today},
 });

 // player repository is injected through constructor
 var controller = new HomeController(mockPlayerRepo.Object);

// ACT 
// game repository is injected through action parameter
var result = controller.Index(mockGameRepo.Object); 

// ASSERT our action result and model
var viewResult = Assert.IsType(result);
var model = Assert.IsAssignableFrom(viewResult.ViewData.Model);
Assert.Equal(2, model.Players.Count);
Assert.Equal(3, model.Games.Count);
}

Nothing radically different in this test than what we just did in our custom TeamStatCalculator one. We're using "aaa", we mock up some dependencies for PlayerRepository and GameRepository, inject them into our controller then call its Index() action method. The biggest difference is in the assertion where we're looking at the ViewResult and model to make sure they're returning what we expect. Other than that, it's safe to say that writing and structuring tests for custom logic AND controllers is practically the same...sweet! 🙂

Wrapping up

Well friend, if you're still with me - you rock!!

Right now between the last post and what we've just covered I hope you have a clearer picture of how IoC/DI and unit tests all work together in ASP.NET Core to help produce higher-quality software that is easier and faster to test, fix and change.

The best way to truly understand and feel the benefits of these concepts is to put them into action yourself. So, I challenge you to do so in your next project and experience first hand how they can improve your life as a developer.

Thanks for reading and please drop any questions or feedback in the comments below!

Source code