Need Integration Testing crash course

Unit testing controllers seems like a complete waste of time.

No point in testing code not written by you (.NET Core Web API). Now you need to mock the validation part, because it is not running through the automatic middleware.

If you want to test your validation in the controllers, use integration testing.
 
Unit testing controllers seems like a complete waste of time.

No point in testing code not written by you (.NET Core Web API). Now you need to mock the validation part, because it is not running through the automatic middleware.

If you want to test your validation in the controllers, use integration testing.

It does feel like a waste of time yes. I would rather unit test the services with say a mock dbcontext in memory

As for testing validation on controllers I have that all completed and running in the integration testing project.

Just trying to wrap my head now around unit testing/moq and such.
 
I think after all of this I am going to make a tutorial with what little I know so far about writing tests (unit and integration), then setting up the yaml pipline file for testing and deployment, and then getting to automatically deploy to azure devops and then onto azure production for it to be live.

At this point I am looking at getting my serilog to log into azure data storage, either tables or blob. And then setting up an SQL instance on azure and eventually be able to have the entire api just running on azure itself.

The last week or so has been a steep learning curve so I will try to document what I did and perhaps put it here in this forum subsection. It's not difficult but there are lots of small steps.
 
Please can you guys give me some quick advice on deploying a local sql to Azure.

I have the Azure SQL set up. I changed the connection string in my local project to use the Azure one. I ran the project and my migrations fired off and created all the tables and seeded them with test data on my Azure database.

Thing is, I'm hearing some talk about DACPAC's and deploying them through a CI/CD pipeline. I have watched a tutorial on this and it makes sense. What doesn't make sense of having to create a whole new SQL Database Project in VS and deploying that separately to Azure. It seems very fiddly and not quite right to do it this way.

Can I get some suggestions on the correct way to deploy sql to Azure.

Here is the Visual Studio route I mentioned.

 
Last edited:
we dont use DACPAC's, we use EF Core's Migrations.

We then have a console app in our project, that is used to apply the migrations.

Developers use this locally to apply migrations to their local database, and the CI/CD pipeline uses the console application to update the remote database - strictly speaking, our CI/CD builds a docker image of the console application, pushes it to our private docker registry in AWS, and then executes a once of task in AWS Fargate, which the CI/CD waits for it to complete, and then deploys the updated application code.
 
we dont use DACPAC's, we use EF Core's Migrations.

We then have a console app in our project, that is used to apply the migrations.

Developers use this locally to apply migrations to their local database, and the CI/CD pipeline uses the console application to update the remote database - strictly speaking, our CI/CD builds a docker image of the console application, pushes it to our private docker registry in AWS, and then executes a once of task in AWS Fargate, which the CI/CD waits for it to complete, and then deploys the updated application code.

EF migrations huh. I'm wondering how the pipeline actually runs the console app or whatever it does. That's complicated af lol.
 
EF migrations huh. I'm wondering how the pipeline actually runs the console app or whatever it does. That's complicated af lol.
it's not at all, if you are using Azure Devops, this is trivial, as there are already dotnet cli task's built in, so you can just execute `dotnet run NameOfMigrationsProject`
 
it's not at all, if you are using Azure Devops, this is trivial, as there are already dotnet cli task's built in, so you can just execute `dotnet run NameOfMigrationsProject`

I'm calling this for now. Will just set it in my connection string. I can't fathom running migrations from a separate project. At the moment I run them from within my Program.cs. and that is all I know. And as for the cli commands, I barely even know what that is or how to use them.

I appreciate the advice though it is something to consider in future. For now I will just explore with running the DACPACs as it is more straight forward..
 
I mean that will work, it’s just not close to pro.

Our production databases are not even accessible via the internet.

Ef migrations are much simpler than DACPAC, seeing as you already do them in your Startup.cs

An dot core console application is IDENTICAL to web application, except that a different SDK is declared in the top of the csproj file.

But learn everything anyway :)

For us, having our application run it’s own migrations is unacceptable. Especially as we run a minimum of 2 instances. Imagine 2 ( or 4 or 100) applications all trying to apply the same migrations at the same time.
 
I mean that will work, it’s just not close to pro.

Our production databases are not even accessible via the internet.

Ef migrations are much simpler than DACPAC, seeing as you already do them in your Startup.cs

An dot core console application is IDENTICAL to web application, except that a different SDK is declared in the top of the csproj file.

But learn everything anyway :)

For us, having our application run it’s own migrations is unacceptable. Especially as we run a minimum of 2 instances. Imagine 2 ( or 4 or 100) applications all trying to apply the same migrations at the same time.

Is it not the same as it running it's own migrations when they are run from the cli on the pipeline?

I forgot that one could actually target the project where the dbcontext lies, when running migration commands doh.

I won't dump this though. I'll ponder on what you have said, possibly a few days or weeks and come back to it every now and then. It is a much better way yes as you have much more control over what is being deployed/migrated.
 
Is it not the same as it running it's own migrations when they are run from the cli on the pipeline?

I forgot that one could actually target the project where the dbcontext lies, when running migration commands doh.

I won't dump this though. I'll ponder on what you have said, possibly a few days or weeks and come back to it every now and then. It is a much better way yes as you have much more control over what is being deployed/migrated.
The nice thing about a console app is that when you run it it starts and stops, unless you code it to wait for input/run in the background. A web app on the other hand starts and stays running.

Here is the migration console app in it’s entirety:

C#:
   class Program
    {
        public static ApplicationContext CreateDbContext(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", true, true)
                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true)
                .AddEnvironmentVariables()
                .Build();

            var connectionString = configuration.GetConnectionString("sqlConnection");
            var serverVersion = new MariaDbServerVersion(new Version(5, 5, 12));

            var optionsBuilder = new DbContextOptionsBuilder<ApplicationContext>()
                .UseMySql(connectionString, serverVersion, builder => builder.MigrationsAssembly("YourProject.Model"));
            return new ApplicationContext(optionsBuilder.Options);
        }

        static void Main(string[] args)
        {
            using var context = CreateDbContext(args);
            var migrations = context.Database.GetPendingMigrations().ToList();

            migrations.ForEach(System.Console.WriteLine);

            if (migrations.Any())
            {
                System.Console.WriteLine($"Executing {migrations.Count} db operations");

                context.Database.Migrate();
            }
            else
            {
                System.Console.WriteLine("Database up to date. No migrations to run");
            }

            //Run seed methods here...
            context.SaveChanges();
        }
    }
 
Ah that is a big help thanks @_kabal_

Yeah that is great I get what you are saying, to then run this from the cli. What I'll do is try and plug this into the yaml script. Should be straight forward enough I mean, I do run my test projects from there as such. The whole DACPAC thing; feels like I'm boxing everything up, wrapping tape around it and sending it off.

YAML:
steps:

- task: DotNetCoreCLI@2
  inputs:
   command: test
   projects: '**/*tests/*.csproj'
   arguments: '--configuration $(buildConfiguration)'
 
Last edited:
Ah that is a big help thanks @_kabal_

Yeah that is great I get what you are saying, to then run this from the cli. What I'll do is try and plug this into the yaml script. Should be straight forward enough I mean, I do run my test projects from there as such. The whole DACPAC thing; feels like I'm boxing everything up, wrapping tape around it and sending it off.

YAML:
steps:

- task: DotNetCoreCLI@2
  inputs:
   command: test
   projects: '**/*tests/*.csproj'

Yeah it will basically be

YAML:
steps:

- task: DotNetCoreCLI@2
  inputs:
   command: run
   projects: 'ProjectName'

If your project isn’t in your repo root, then adjust “projects” accordingly.

You can also setup environment variables for the connection string per branch, so if you are building “develop” you can inject the dev db, but for master inject the prod db

Environment variables can use “:” or “__”

So if your app settings says
ConnectionStrings: {
MyContext: “the connection string”
}
You can declare an environment variable called “ConnectionStrings:MyContext” or “ConnectionStrings__MyContext”
 
Last edited:
Yeah it will basically be

YAML:
steps:

- task: DotNetCoreCLI@2
  inputs:
   command: run
   projects: 'ProjectName'

If your project isn’t in your repo root, then adjust “projects” accordingly.

You can also setup environment variables for the connection string per branch, so if you are building “develop” you can inject the dev db, but for master inject the prod db

Environment variables can use “:” or “__”

So if your app settings says
ConnectionStrings: {
MyContext: “the connection string”
}
You can declare an environment variable called “ConnectionStrings:MyContext” or “ConnectionStrings__MyContext”

Yeah it's arguing with me a little :X3:

migrationsfailing.jpg
 
Yeah 2 hours and cannot get rid of that error. Tried playing with all different path settings and suggestions from stackoverflow. It is what it is.
 
Yeah 2 hours and cannot get rid of that error. Tried playing with all different path settings and suggestions from stackoverflow. It is what it is.

For what ever reason your file location isn't being matched, check that the file name and path actually match. Is your project perhaps in /src/Migrations/Migrations.csproj?

You could also try explicitly setting the workingDirectory?

You could also try using wildcards? e.g. **/*.csproj

Hope that helps?
 
Yeah 2 hours and cannot get rid of that error. Tried playing with all different path settings and suggestions from stackoverflow. It is what it is.
Your project isn’t called ‘src/Migrstions.csproj’, its ‘src/Migrations’

Run “dotnet run src/Migrations” locally and you will see it works
 
Your project isn’t called ‘src/Migrstions.csproj’, its ‘src/Migrations’

Run “dotnet run src/Migrations” locally and you will see it works

That fixed it thanks :thumbsup:

It's working beautifully. That concludes at least for now the whole learning process of building a software solution, setting up build and deployment pipelines onto Azure itself whereby it is then running live.

I was even able to register on the API through the SwaggerUI and get a registration email!

Thanks a ton for all your help @_kabal_ and to everyone else in this thread.

awaiterror.jpg
 
Last edited:
Top
Sign up to the MyBroadband newsletter
X