Creating and Running Tests

Building out the test project

NOTE: the initial test project should have been created as an xUnit project. Towards that end I have added the command:

yo aspnet xunit Pubs.Data.Test --version-current

to the yoCommands.txt file and run it to use that as the test project.

To create tests we will need to open up the Pubs.Data.Test project, then either delete the Class1.cs file, then add a new class named StoresTest, or else rename the Class1 class to StoresTest. Next open up the csproj file and add the following lines to dependencies, either manually or by using the NuGet Package Manager extension of VS Code:

"Pubs.Data": "1.0.0-*"
”Microsoft.EntityFrameworkCore”: “1.1.0”,
"Microsoft.Extensions.Configuration.Binder": "1.1.0",
"Microsoft.Extensions.Configuration.CommandLine": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0"

Another way to add references, either to NuGet packages or other projects is to use the dotnet cli tool. (Details can be found at the dotnet-add reference help page, and here.) The following command will provide help on how to do so:

dotnet add reference –h

so, for example, typing:

dotnet add reference ..\Pubs.Data\Pubs.Data.csproj

will add the ef data project. Similarly, substituting package for reference allows one to add a NuGet package. So, for example, one can add the Binder reference thusly:

dotnet add package Microsoft.Extensions.Configuration.Binder

Either approach will add the references to the Pubs.Data project, as well as the assemblies to access the appsettings.json file. (Keep in mind that I have excluded that file from git.) Having said this one will also need to add “appsettings.json” to the .csproj file. Here is how it looks in the project.json format:

"buildOptions": {
    "copyToOutput": {
      "include": [ "xunit.runner.json", "appsettings.json" ]
    }
  }

To accomplish the same result in the Pubs.Data.Test.csproj file, the following section will need to be added:

<ItemGroup>
  <None Update="xunit.runner.json;appsettings.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

From there I build the constructor so:

public StoresTest(ITestOutputHelper output)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables()
                ;
            builder.Build();
            Configuration = builder.Build();

            string connection = Configuration.GetSection("ConnectionStrings").GetValue<string>("Sample");
            DbContextOptions contextOptions = new DbContextOptionsBuilder().UseSqlServer(connection).Options;
            _dbContext = new PubsDbContext(contextOptions);
            _pubsStores = _dbContext.PubsStores;
        }

Keep in mind that I added a constructor overload to the context that accepts a DbContextOptions object.

Creating Tests

I have added 3 test methods on the Stores table: CountStores, AddStore, and RemoveStores. A core principle of testing is that the tests should be repeatable and independent of any of the other tests or the order in which they are run. I also have a class level field named _newStoreName. I will use that name when adding a new store, as well as to search for any stores that I can delete since I am using a database whose untegrity I which to maintain. In CountStores I check that there are, in fact, stores in the database, and that there are 6 not named with the new name. I accomplish this with this code:

Assert.NotEqual (0, _pubsStores.Count ());
Assert.Equal (6, _pubsStores.Count<PubsStores> (s => s.StorName != _newStoreName));

Now in my AddStore method I can check the number of stores with the new name, add another and verify that there is one more. To make sure that I am getting the most recent data from the database, I refactored out the code to load the dbcontext, and I use that in the constructor and in the add method. Finally in the RemoveStores method I look for all stores named the value of the _newStoreName field, and delete them, then verify that there are, in total, the same number of stores in the database as there were stores without the new name, after, again, reloading the context.

Additional tests can be left as an exercise to the reader.

Running the tests

In order to run the tests I simply went to a command prompt, changed to the project with the tests, then executed the dotnet test command. If anyone gets the code from the repository, they will see some Console.Write commands commented out. If one uncomments them then they will see the progress of the tests.

Resources

Here are some good resources that I found that may be of help with xUnit tests:

Updating git

The following commands will update both the local and remote repositories:

git add .
git commit -m"Coded the Pubs.Data and Pubs.DTO projects and wrote tests for Stores table"
git push origin Setup_Projects

No Comments

Add a Comment