The Monsters Weekly - Episode 87 - Building a Roslyn Analyser

If you’ve used Visual Studio 2015 then you’ve used the Roslyn managed compiler. Roslyn is unlike most any other compiler in that it offers a simple approach to adding your own warnings and errors to the build pipeline. In this episode we’ll build a simple analyser. Our American friends might know these as "Analyzers".

 

References

C# and Visual Basic - Use Roslyn to Write a Live Code Analyzer for Your API

The Monsters Weekly - Episode 86 - Pugzor

Earlier in November, the ASP.NET Monsters had the opportunity to take part in the ASP.NET Core hackathon at the Microsoft MVP Summit. In past years, we have used the hackathon as an opportunity to spend some time working on GenFu. This year, we wanted to try something a little different.

In this episode, we explore our monstrous creation: Pugzor, an alternate view engine for MVC built with Pug and Node Services.

Related Links:

Episode #82 - Node Services

Pugzor on GitHub

Blog Post

 

The Monsters Weekly - Episode 85 - Suave Web Services

We love ASP.NET but we also love web stuff in general. In today’s episode we take a quick look at building a simple service using Suave the F# web framework. 

 

References:

Suave Web Services

suave.io

Chiron

Suave Web Services

I’m on this quest to learn F#. It is a multi-year project because of a couple of reasons

  • I don’t spend enough time on it
  • I’m not very bright

Today’s adventure has been using the Suave.io which is a web framework library and web server. If you’re looking to throw up a quick web service to act as a microservice it doesn’t get much lighter weight than Suave. At the same time you can make more complex processes if necessary.

The Monsters Weekly - Episode 84 - Integration Testing with Entity Framework Core

Entity Framework Core makes it easy to write tests that execute against an in-memory store but sometimes we want to actually run our tests against a real relational database. In this episode, Monster Dave looks at how to create an integration test that runs against a real SQL Server database.

Blog Post
GitHub Repo

Follow @aspnetmonsters

The Monsters Weekly - Episode 83 - A Book on ASP.NET Core

Today we have the pleasure of announcing the release of a new source of reference for building an application in ASP.NET Core MVC.
 
Over the last two years we have had the great fortune of serving the ASP.NET community, sharing in our learning, getting tonnes of feedback and having a great time exploring the next version of ASP.NET.  In this episode, we shamelessly plug the table of contents for our newly released book. Join the Monsters to hear more about what is sure to be a timeless classic, coffee table material in every household.
 
 

Get the Book on ASP.NET Core MVC

Announcing the Microsoft Press “ASP.NET Core Application Development” Book from the ASP.NET Monsters

Buy Now

ASP.NET Core Application Development

Through four complete sprints, this book takes you through every step needed to build brand new cross-platform web apps with ASP.NET Core, and make them available on the Internet. You won’t just master Microsoft’s revolutionary open source ASP.NET Core technology: you’ll learn how to integrate the immense power of MVC, Docker, Azure Web Apps, Visual Studio and Visual Studio Code, C#, JavaScript, TypeScript, and Entity Framework.

Working through the authors’ carefully designed sprints, you’ll start with a blank canvas, move through software architecture and design, adjusting to user feedback, recovering from mistakes, builds, testing, deployment, maintenance, refactoring, and more. Along the way, you’ll learn techniques for delivering state-of-the-art software to users more rapidly and repeatably than ever before.

The Monsters Weekly - Episode 82 - Node Services

I can’t remember if NodeJS is still cool or if people are only using it ironically now as they port their applications to something else. In either case there are still a lot of great node modules out there which it would be great to access from our ASP.NET application. In this episode we’ll look at Node Services an approach to call out to Node from inside an ASP.NET MVC Core controller. 

 

 

Integration Testing with Entity Framework Core and SQL Server

Originally posted to: http://www.davepaquette.com/archive/2016/11/27/integration-testing-with-entity-framework-core-and-sql-server.aspx

Entity Framework Core makes it easy to write tests that execute against an in-memory store. Using an in-memory store is convenient since we don’t need to worry about setting up a relational database. It also ensures our unit tests run quickly so we aren’t left waiting hours for a large test suite to complete.

While Entity Framework Core’s in-memory store works great for many scenarios, there are some situations where it might be better to run our tests against a real relational database. Some examples include when loading entities using raw SQL or when using SQL Server specific features that can not be tested using the in-memory provider. In this case, the tests would be considered an integration test since we are no longer testing our Entity Framework context in isolation. We are testing how it will work in the real world when connected to SQL Server.

The Sample Project

For this example, I used the following simple model and DbContext classes.

public class Monster
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsScary { get; set; }
public string Colour { get; set; }
}
public class MonsterContext : DbContext
{
public MonsterContext(DbContextOptions<MonsterContext> options)
: base(options)
{
}
public DbSet<Monster> Monsters { get; set; }
}

In an ASP.NET Core application, the context is configured to use SQL Server in the Startup.ConfigureServices method.

services.AddDbContext<MonsterContext>(options =>
{
options.UseSqlServer("DefaultConnection");
});

The DefaultConnection is defined in appsettings.json which is loaded at startup.

{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=monsters_db;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}

The MonsterContext is also configured to use Migrations which were initialized using the dotnet ef migrations add InitialCreate command. For more on Entity Framework Migrations, see the official tutorial.

As a simple example, I created a query class that loads scary monsters from the database using a SQL query instead of querying the Monsters DbSet directly.

public class ScaryMonstersQuery
{
private MonsterContext _context;
public ScaryMonstersQuery(MonsterContext context)
{
_context = context;
}
public IEnumerable<Monster> Execute()
{
return _context.Monsters
.FromSql("SELECT Id, Name, IsScary, Colour FROM Monsters WHERE IsScary = {0}", true);
}
}

To be clear, a better way to write this query is _context.Monster.Where(m => m.IsScary == true), but I wanted a simple example. I also wanted to use FromSql because it is inherently difficult to unit test. The FromSql method doesn’t work with the in-memory provider since it requires a relational database. It is also an extension method which means we can’t simply mock the context using a tool like Moq. We could of course create a wrapper service that calls the FromSql extension method and mock that service but this only shifts the problem. The wrapper approach would allow us to ensure that FromSql is called in the way we expect it to be called but it would not be able to ensure that the query will actually run successfully and return the expected results.

An integration test is a good option here since it will ensure that the query runs exactly as expected against a real SQL Server database.

The Test

I used xunit as the test framework in this example. In the constructor, which is the setup method for any tests in the class, I configure an instance of the MonsterContext connecting to a localdb instance using a database name containing a random guid. Using a guid in the database name ensures the database is unique for this test. Uniqueness is important when running tests in parallel because it ensures these tests won’t impact any other tests that aer currently running. After creating the context, a call to _context.Database.Migrate() creates a new database and applies any Entity Framework migrations that are defined for the MonsterContext.

public class SimpleIntegrationTest : IDisposable
{
MonsterContext _context;
public SimpleIntegrationTest()
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkSqlServer()
.BuildServiceProvider();
var builder = new DbContextOptionsBuilder<MonsterContext>();
builder.UseSqlServer($"Server=(localdb)\\mssqllocaldb;Database=monsters_db_{Guid.NewGuid()};Trusted_Connection=True;MultipleActiveResultSets=true")
.UseInternalServiceProvider(serviceProvider);
_context = new MonsterContext(builder.Options);
_context.Database.Migrate();
}
[Fact]
public void QueryMonstersFromSqlTest()
{
//Add some monsters before querying
_context.Monsters.Add(new Monster { Name = "Dave", Colour = "Orange", IsScary = false });
_context.Monsters.Add(new Monster { Name = "Simon", Colour = "Blue", IsScary = false });
_context.Monsters.Add(new Monster { Name = "James", Colour = "Green", IsScary = false });
_context.Monsters.Add(new Monster { Name = "Imposter Monster", Colour = "Red", IsScary = true });
_context.SaveChanges();
//Execute the query
ScaryMonstersQuery query = new ScaryMonstersQuery(_context);
var scaryMonsters = query.Execute();
//Verify the results
Assert.Equal(1, scaryMonsters.Count());
var scaryMonster = scaryMonsters.First();
Assert.Equal("Imposter Monster", scaryMonster.Name);
Assert.Equal("Red", scaryMonster.Colour);
Assert.True(scaryMonster.IsScary);
}
public void Dispose()
{
_context.Database.EnsureDeleted();
}
}

The actual test itself happens in the QueryMonstersFromSqlTest method. I start by adding some sample data to the database. Next, I create and execute the ScaryMonstersQuery using the context that was created in the setup method. Finally, I verify the results, ensuring that the expected data is returned from the query.

The last step is the Dispose method which in xunit is the teardown for any tests in this class. We don’t want all these test databases hanging around forever so this is the place to delete the database that was created in the setup method. The database is deleted by calling _context.Database.EnsureDeleted().

Use with Caution

These tests are slow! The very simple example above takes 13 seconds to run on my laptop. My advice here is to use this sparingly and only when it really adds value for your project. If you end up with a large number of these integration tests, I would consider splitting the integration tests into a separate test suite and potentially running them on a different schedule than my unit test suite (e.g. Nightly instead of every commit).

The Code

You can browse or download the source on GitHub.

The Monsters Weekly - Episode 81 - Invoking View Components as Tag Helpers

A new feature in ASP.NET Core 1.1 allows us to invoke view components as tag helpers. Monster Dave shows us how to enable this new feature.

Related Episode - View Components