Skip to main content

# Integration testing

When it comes to implement integration tests, there is a lot of debate. Aren't unit tests enough? What are you trying to cover with them?

- in the `Tests` folder, add a new xUnit project named `SpeakerService.Tests.Integration`

We will add a helper class that extends `WebApplicationFactory<TProgram>`. This will allow us to configure a database used for tests(if- and we should use a different test database), and also allow us to create additional methods in-charge of channel creation.

Creating a custom Factory

    public class MyFactory<TProgram> : WebApplicationFactory<TProgram> where
           TProgram : class
        {

        }

- Configure the WebHost

Configure the WebHost

     protected override void ConfigureWebHost(IWebHostBuilder builder)
            {
                builder.UseEnvironment("Test");
                //builder.UseTestServer();
                builder.ConfigureTestServices(services =>
                {
                   //in here we configure what we need
                });
                builder.UseTestServer();
            }

- Create an additional method that will return a gRPC client

CreateGrpcClient method

    public SpeakerServiceDefinition.SpeakerServiceDefinitionClient CreateGrpcClient()
            {
                var httpClient = CreateClient();

                var channel = GrpcChannel.ForAddress(httpClient.BaseAddress!, new GrpcChannelOptions
                {
                    HttpClient = httpClient,
                });

                return new SpeakerServiceDefinition.SpeakerServiceDefinitionClient(channel);
            }

# Writing the test class

- add a class named `SpeakerServiceTests` that extends our `MyFactory` class

Title

    public class SpeakerServiceTests : IClassFixture<MyFactory<Program>>
    {

    }

- prepare the constructor, passing the right

    private readonly MyFactory<Program> factory;

    public SpeakerServiceTests(MyFactory<Program> factory)
    {
      this.factory = factory;
    }

- write the test method applying the AAA pattern

The test objects

We should work on a test database, that is seeded with some test data, or create some objects, insert them in the db, and then make assertions using them

- Arrange - call the factory to obtain a gRPC client, build an object that you know will be the response object

                // Arrange
                var client = factory.CreateGrpcClient();
                var expectedResponse = new SpeakerResponse()
                {
                    Id = 5,
                    City = "Oslo",
                    Country = "Norway",
                    Email = "",
                    Bio = "",
                    FirstName = "",
                    LastName = "",
                    Website = ""
                };

- Act

Act

     var response = await client.GetByIdAsync(new SpeakerFilterRequest { Id = 5 });

- Assert

Act

    response.Should().BeEquivalentTo(expectedResponse);

DON't open
Full implementation

      public class SpeakerServiceTests : IClassFixture<MyFactory<Program>>
        {
            private readonly MyFactory<Program> factory;

            public SpeakerServiceTests(MyFactory<Program> factory)
            {
                this.factory = factory;
            }

            [Fact]
            public async Task GetById_Async()
            {
                // Arrange
                var client = factory.CreateGrpcClient();
                var expectedResponse = new SpeakerResponse()
                {
                    Id = 5,
                    City = "Oslo",
                    Country = "Norway",
                    Email = "",
                    Bio = "",
                    FirstName = "",
                    LastName = "",
                    Website = ""
                };

                var response = await client.GetByIdAsync(new SpeakerFilterRequest { Id = 5 });

                // Assert
                response.Should().BeEquivalentTo(expectedResponse);
            }

        }