ICYMI C# 8 New Features: Write Less Code with Using Declarations

This is part 2 in a series of articles.

One nice little enhancement introduced in C# 8 helps to simplify code that uses disposable objects.

For example consider the following:

class MyDisposableClass : IDisposable
{
    public void Dispose()
    {            
        Console.WriteLine("Disposing");
    }

    public void Run() 
    {
        Console.WriteLine("Running");
    }
}

Prior to C# 8, if you wanted to use a disposable object (something that implements IDisposable) then you would usually use a using block as follows:

private static void Process()
{
    using (var x = new MyDisposableClass())
    {
        x.Run();
    }
}

At the end of the using block, the Dispose() method is called automatically.

With C# 8, instead of the using block, you can instead use a using declaration:

private static void Process()
{
    using var x = new MyDisposableClass();

    x.Run();
}

Notice in the preceding code, with a using declaration there is no need for the additional {}. When using a using declaration, the Dispose() method is called automatically at the end of the Process() method. Just as with the using block approach, if an exception occurs within the Process() method then Dispose() will still be called.

Using declarations help to keep code less cluttered because you have fewer braces {} and one level less of indenting.

If you have multiple usings, for example:

private static void Process()
{
    using (var x = new MyDisposableClass())
    using (var y = new MyDisposableClass())
    using (var z = new MyDisposableClass())
    {
        x.Run();
        y.Run();
        z.Run();
    }
}

You can rewrite this in C# 8 as follows:

private static void Process()
{
    using var x = new MyDisposableClass();
    using var y = new MyDisposableClass();
    using var z = new MyDisposableClass();

    x.Run();
    y.Run();
    z.Run();
}

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

ICYMI C# 8 New Features: Switch Expressions

In the first part of this series on what was introduced in C# 8, we’re going to take a look at switch expressions.

Switch expressions allow you to write fewer lines of code when making use of switch statements. This is useful if you have a switch statement that sets/returns a value based on the input.

Prior to C# 8, the following code could be used to convert an int to its string equivalent:

string word;
switch (number)
{
    case 1:
        word = "one";
        break;
    case 2:
        word = "two";
        break;
    case 3:
        word = "three";
        break;
    default:
        throw new ArgumentOutOfRangeException(nameof(number));                    
}

In the preceding code if the input int number is not 1,2, or 3 an exception is thrown, otherwise the variable word is set to the string representation “one”, “two”, or “three”.

From C# 8 we could instead use a switch expression. A switch expression returns a value, this means we can return the string into the word variable as follows:

string word = number switch
{
    1 => "one",
    2 => "two",
    3 => "three",
    _ => throw new ArgumentOutOfRangeException(nameof(number))
};

Compare this version with first version and you can see we have a lot less code, we don’t have all the repetitive case and breaks.

Also notice that the default block has been replaced with an expression that throws the exception. Also notice that the code makes use of a discard _ as we don’t care about the value. (Discards are “placeholder variables that are intentionally unused in application code” (MS)).

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

No App Is An Island

No app is an island entire of itself; every app
is a piece of the continent, a part of the main

(Apologies to John Donne)

It’s very easy to be so focussed (either as a developer/team/department) on a single app/website/etc. that its place in the “continent” can be forgotten. This is not really a fault of the individual developer/team, rather more an organization problem.

Take the example of a bank’s mobile app in the app store. The journey of a person and the app is much bigger than just using the app itself. How did the person hear about the app in the first place and how did they find it in the app store (just by searching or did the bank have a poster with a QR code on it?), do they log into the app with existing Internet banking details (and if so how did they set up their account – on the banks website?), what happens when they close their accounts or want to uninstall the app? What happens if there is a problem with the app and they phone the call centre? If a new version of the app is released that doesn’t work will that cause an influx of calls to the call centre, overloading its capacity and potentially missing out on sales opportunities from other calls?

At a more technical level, what APIs does the app call into, do those APIs in turn interface with other systems (e.g. a banking mainframe). If the mainframe errors what effect does that have on the API and thus the app and the person using the app?

If a customer has a problem with the app and goes into a bank for help, are the customer service representatives there able to help? If not do they have a “hotline” number to  get straight through to IT/specialist app support personnel?

As developers we are also all consumers of software, sometimes this gives us more patience – sometimes less – when things are designed badly or don’t work.

If as software developers we get frustrated what is the “normal” person using software feeling?

Perhaps it’s time that every sufficiently large company had a dedicated user experience team that is intimately familiar with the entire “continent”/user journey. These “UX user champions” can then be part of development teams to ensure that indeed, no app is an island.

SHARE:

How to Make 2021 Your Best Year Ever

Happy New Year!

I think we can all agree that 2020 was one of the most challenging years any of us have experienced. Even though here in Western Australia we have been relatively lucky due to our isolation – we even had our border to the rest of Australia closed, let alone international travel… I’ve had close friends in other countries contract Covid, luckily they are ok.

One thing 2020 has helped me learn is to really try and differentiate between the things I can control and the things I can’t.

If you’ve been a reader of my blog for some time you’ll now I make heavy use of the 3 Wins Technique. I just set my 3 big wins for 2021 and what I realized was that my 2020 wins were, in reality, not things I could  control.

I’m not saying having goals that are not 100% controllable is a bad idea, for example having a general savings/investments/paying off debts goal is fine. However you don’t control interest rates or share prices for example.

I still believe the 3 Wins Technique is a simple and effective tool, this year however I am going to be more conscious of setting goals that are in my control.

As a hypothetical  example, suppose one of your 3 wins is to “get a pay rise”. This is out of your control. I know that sounds negative, but you can’t force your employer to give you a pay rise. A better goal would be something like “I’m going to learn as much as I can this year and add as much value as I can”. This should lead to the opportunity to have a discussion with your employer and show them the extra value you’ve added and talk about a pay rise. Of course the answer could still be “no”, at which point you can control whether or not you apply for jobs elsewhere – you’ll now have more skills to offer a new employer.

As another example: “get 1000 subscribers/followers on [INSERT SOCIAL MEDIA PLATFORM HERE]”. This is also not in your control. A better version: “I’m going to learn everything I can about how [INSERT SOCIAL MEDIA PLATFORM HERE] works, I’m going to learn how to create valuable content, and I’m going to cross-market my content on the other platforms”. Again, it’s about reframing what you can and cannot control.

It’s likely that 2021 will be another challenging year, but if you set your “wins” based on things you can control and work hard to make them happen, you‘re more likely to finish 2021 with a sense of achievement rather than disappointment.

Best wishes,

Jason.

SHARE:

Goodbye 2020, Hello 2030

It has felt like a looong year. We have been relatively lucky here in Australia and especially so in Western Australia. We still went through the toilet paper panic, the handwash shortages, and the travel restrictions between regions within Western Australia and worldwide. Even so, with friends and family situated around the world it has been a mentally taxing year for most people. If you have lost loved ones, you have my sincere sympathies.

However, a year in the scope of a full lifetime is is merely a small fragment and what you can achieve in 10 years can be truly astonishing. The 24 hour news cycle is an even smaller fragment.

As 2020 draws to a close, ask yourself where you want to be in 2030, who you want to be with, what work you want to be doing, how healthy will you be?

As a race, humans are capable of some truly horrible things but also some truly wonderful, beautiful, awe-inspiring things and good is the norm.

As we head into 2021, I want to wish you the happiest holidays possible and for those that celebrate it a Merry Christmas.

Best wishes for the new year.

Be kind to yourself and others.

Things will get better.

Jason.

SHARE:

New Pluralsight Course: Feature Flag Fundamentals with Microsoft Feature Management

My latest Pluralsight video training course was just published just in time for some holiday season learning! :)

From the description: “Releasing software to production can be hard, risky, and time-consuming, especially if there is a problem and you need to roll back the deployment. In this course, Feature Flags Fundamentals and Microsoft Feature Management, you’ll gain the ability to effectively and efficiently manage the development and deployment of features. First, you’ll explore how to configure and use feature flags in code. Next, you’ll discover how to control features and HTML rendering using Microsoft feature flags in an ASP.NET Core app. Finally, you’ll learn how to customize Microsoft Feature Management and even manage features from Azure. When you’re finished with this course, you’ll have the skills and knowledge of Microsoft Feature Management needed to effectively deploy and manage features in production.”

You can read more about the course over on the official course homepage. Or start watching with a free trial today.

SHARE:

Approval Tests: Assert With Human Intelligence

In the previous article I described how the Approval Tests library can help reduce the amount of assert code that needs to be written. The second benefit of using Approval Tests is the ability to use innate human intelligence to decide if the result of the test is correct.

Imagine a scenario where you need to assert that a text-to-speech generator has generated the correct output. In this example the output could be a byte array representing a .WAV or .MP3 sound file. How would you write traditional asserts to test this output?

As another example, suppose you had to test code that applied a creative filter to an input photograph, this could be some sort of “make skin tones look nice” filter, the output in this case would be a modified image file. How would you assert that the output photo looked “nice”?

In cases like these using traditional asserts may be impossible or very time consuming to implement, there is no Assert.Speech(…) or Assert.LooksNice(…).

This is where the Approval Tests library offers great benefits. You could simply write Approvals.Verify(speechWavBytes); or Approvals.Verify(processedImageBytes); In the case of the sound file you could listen to it and decide if it sounds correct. In the case of the processed photo, you could look at it on screen and use human intelligence to decide if it “looks nice”.

Once you are happy you can approve the results and then in future tests runs if the output accidentally changes due to a bug the tests will fail.

If you want to see Approval Tests in action and learn more about how they can make your testing life easier check out my Approval Tests for .NET Pluralsight course which you can currently start watching for free today with a Pluralsight free trial.

SHARE:

Approval Tests: Write Tests More Quickly

Sometimes assert code in tests gets big and messy and complicated when the output we’re testing is complex.

Approval Tests is a library that can help simplify assert code. The library has other benefits/use cases which I’ll cover in future posts such as using human intelligence to judge if the output is correct; providing a safety net when refactoring legacy code that has no tests; and even testing view rendering.

In the following test code, notice the assert phase:

[Fact]
public void TraditionalAsserts()
{
    var lines = new List<string>
    {
        "Widget sales: 42",
        "Losses: 99",
        "Coffee overheads: 9,999,999"
    };

    var sut = new ReportGenerator(title: "Annual Report",
                                    footer: "Copyright 2020",
                                    lines);

    string report = sut.Generate();

    // Notice the complexity of the asserts below
    Assert.Equal("Annual Report", report.Split(Environment.NewLine)[0]);
    Assert.Equal("Widget sales: 42", report.Split(Environment.NewLine)[2]);
    Assert.Equal("Losses: 99", report.Split(Environment.NewLine)[3]);
    Assert.Equal("Coffee overheads: 9,999,999", report.Split(Environment.NewLine)[4]);
    Assert.Equal("Total lines: 3", report.Split(Environment.NewLine)[6]);
    Assert.Equal("Copyright 2020", report.Split(Environment.NewLine)[8]);
            

    // We could also have just asserted using a long expected string rather than individual line asserts
}

And for reference the ReportGenerator class looks like the following:

public class ReportGenerator
{
    public string Title { get; }
    public List<string> Lines { get; }
    public string Footer { get; }

    public ReportGenerator(string title, string footer, List<string> lines)
    {
        Title = title;
        Footer = footer;
        Lines = lines;
    }

    public string Generate()
    {
        var report = new StringBuilder();

        report.AppendLine(Title);
        report.AppendLine();

        foreach (var line in Lines)
        {
            report.AppendLine(line);
        }


        report.AppendLine();
        report.AppendLine($"Total lines: {Lines.Count}");

        report.AppendLine();
        report.AppendLine(Footer);

        return report.ToString();
    }
}

So in the test there are 6 lines of assert code:

Assert.Equal("Annual Report", report.Split(Environment.NewLine)[0]);
Assert.Equal("Widget sales: 42", report.Split(Environment.NewLine)[2]);
Assert.Equal("Losses: 99", report.Split(Environment.NewLine)[3]);
Assert.Equal("Coffee overheads: 9,999,999", report.Split(Environment.NewLine)[4]);
Assert.Equal("Total lines: 3", report.Split(Environment.NewLine)[6]);
Assert.Equal("Copyright 2020", report.Split(Environment.NewLine)[8]);

If the output was more complex or bigger (for example 100’s or 1000’s of lines of text) then the assert code would get even more messy and harder to maintain. Or what if the output was some binary representation such as an array of bytes representing a generated image or text to speech sound file?

It’s in these cases when dealing with complex output that Approval Tests can help to simplify the assert code as shown in the following test:

[Fact]
[UseReporter(typeof(DiffReporter))]
public void ApprovalTestsVersion()
{
    var lines = new List<string>
    {
        "Widget sales: 42",
        "Losses: 99",
        "Coffee overheads: 9,999,999"
    };

    var sut = new ReportGenerator(title: "Annual Report",
                                    footer: "Copyright 2020",
                                    lines);

    string report = sut.Generate();

    Approvals.Verify(report);
}

Notice in the preceding code the line: Approvals.Verify(report); This line calls Approval Tests and will create a new  “received” .txt file in the test project. You can examine this text file and if it is correct rename it to be an “approved” file. When the test runs in the future, Approval Tests will use the approved file (which should be added to source control) and if the generated report is the same then the test will pass, otherwise the test will fail and a new received file will be output. The [UseReporter] attribute lets you specify how to visualize approval failures, in this example by using a diff tool, and there’s a number of other reporters that come out of the box that you can use.

If you want to see Approval Tests in action and learn more about how they can make your testing life easier check out my Approval Tests for .NET Pluralsight course which you can currently start watching for free today with a Pluralsight free trial.

SHARE:

Simplify and Reduce Test Code with AutoFixture

AutoFixture is a library that you can use alongside your testing framework to reduce the amount of boilerplate test code you need to write and thus improve your productivity.

At its core, AutoFixture helps you setup your tests by generating anonymous test data for you. This anonymous test data can be used to fulfil non-important boilerplate test data; this is test data that is required for the test to execute but whose value is unimportant.

Take the follow abbreviated test:

[Fact]
public void ManualCreation()
{
    // arrange

    Customer customer = new Customer()
    {
        CustomerName = "Amrit"
    };

    Order order = new Order(customer)
    {
        Id = 42,
        OrderDate = DateTime.Now,
        Items =
                      {
                          new OrderItem
                          {
                              ProductName = "Rubber ducks",
                              Quantity = 2
                          }
                      }
    };


    // act and assert phases...
}

Suppose the previous test code was only creating an Order (with associated Customer) just to fulfil some dependency and the actual Customer and OrderItems did not matter. In this case we could use AutoFixture to generate them for us.

AutoFixture can be installed via NuGet and once installed allows a Fixture instance to be instantiated. This Fixture object can then be used to generate anonymous test data and greatly simplify the arrange phase, as the following test shows:

[Fact]
public void AutoCreation()
{
    // arrange

    var fixture = new Fixture();

    Order order = fixture.Create<Order>();

    // act and assert phases...
}

If we were to debug this test we’d see the following values:

AutoFixture anonymous test data generation for complex object graphs

Notice in the preceding screenshot that AutoFixture has created the object graph for us, including the Customer and 3 OrderItem instances.

There’s a lot more to AutoFixture than just this simple example, for example you can combine with the AutoFixture.Xunit2 package to further reduce code:

[Theory, AutoData]
public void SubtractWhenZeroTest(int aPositiveNumber, Calculator sut)
{
    // Act
    sut.Subtract(aPositiveNumber);

    // Assert
    Assert.True(sut.Value < 0);
}

If you want to learn more about how AutoFixture can improve your productivity check out the docs or start watching for free  my AutoFixture Pluralsight course with a free trial:

SHARE:

Running xUnit.net Tests on Specific Threads for WPF and Other UI Tests

Sometimes when you write a test with xUnit.net (or other testing frameworks) you may run into problems if UI technologies are involved. This usually relates to the fact that the test must execute using a specific threading model such as single-threaded apartment (STA).

For example suppose you had a WPF app that you wanted to add tests for.

The XAML looks like:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBlock FontSize="42" Text="{Binding Path=Greeting}" />
    </Grid>
</Window>

And the simple quick and dirty view model class looks like:

namespace WpfApp1
{
    public class MainWindowViewModel
    {
        public string Greeting { get; set; }
    }
}

And  in the MainWindow constructor we set the data context:

public MainWindow()
{
    InitializeComponent();

    var vm = new MainWindowViewModel { Greeting = "Hi there!" };
    DataContext = vm;
}

(This is a very simple demo code with no change notifications etc.)

If you wanted to write an xUnit.net test that instantiates an instance of MainWindow, such as:

[Fact]
[UseReporter(typeof(DiffReporter))]
public void RenderWithViewModel()
{
    var sut = new MainWindow();
    var vm = new MainWindowViewModel { Greeting = "Good day!" };
    sut.DataContext = vm;

    // Test rendering, e.g. using Approval Tests
    WpfApprovals.Verify(sut);
}

If you run this, the test will fail with: System.InvalidOperationException : The calling thread must be STA, because many UI components require this.

Note: this test is using Approval Tests (e.g. [UseReporter(typeof(DiffReporter))]) to render the UI into an image file for approval, you can learn more about Approval Tests with my Pluralsight course. Approval Tests is no related to the threading model requirements.

To enable this test to run you need to instruct xUnit to run the test using an apartment model process (“STA thread”).

Luckily Andrew Arnott has done all the hard work for us and created some custom xUnit.net attributes that allow us to specify what thread/synchronization context to use for a test.

Once the Xunit.StaFact NuGet package has been installed into the test project you can replace the standard [Fact] attribute with [StaFact]. The test will now execute without error:

using ApprovalTests.Reporters;
using ApprovalTests.Wpf;
using Xunit;

namespace WpfApp1.Tests
{
    public class MainWindowShould
    {
        [StaFact]
        [UseReporter(typeof(DiffReporter))]
        public void RenderWithViewModel()
        {
            var sut = new MainWindow();
            var vm = new MainWindowViewModel { Greeting = "Good day!" };
            sut.DataContext = vm;

            // Test rendering, e.g. using Approval Tests
            WpfApprovals.Verify(sut);
        }
    }
}

There are also a number of other attributes such as [WinFormsFact] for use with Windows Forms apps, check out the entire list of attributes in the docs.

If you use this library make sure to say a thankyou to Andrew on Twitter  :)

SHARE: