6.2 KiB
title | author | description | monikerRange | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|---|
Test gRPC services in ASP.NET Core | jamesnk | Learn how to test gRPC services in ASP.NET Core apps. | >= aspnetcore-3.1 | jamesnk | mvc | 01/01/2022 | grpc/test-services |
Test gRPC services in ASP.NET Core
Testing is an important aspect of building stable and maintainable software. This article discusses how to test ASP.NET Core gRPC services.
There are three common approaches for testing gRPC services:
- Unit testing: Test gRPC services directly from a unit testing library.
- Integration testing: The gRPC app is hosted in xref:Microsoft.AspNetCore.TestHost.TestServer, an in-memory test server from the
Microsoft.AspNetCore.TestHost
package. gRPC services are tested by calling them using a gRPC client from a unit testing library. - Manual testing: Test gRPC servers with ad hoc calls. For information about how to use command-line and UI tooling with gRPC services, see xref:grpc/test-tools.
In unit testing, only the gRPC service is involved. Dependencies injected into the service must be mocked. In integration testing, the gRPC service and its auxiliary infrastructure are part of the test. This includes app startup, dependency injection, routing and authentication, and authorization.
Example testable service
To demonstrate service tests, review the following service in the sample app.
View or download sample code (how to download)
The TesterService
returns greetings using gRPC's four method types.
The preceding gRPC service:
- Follows the Explicit Dependencies Principle.
- Expects dependency injection (DI) to provide an instance of
IGreeter
. - Can be tested with a mocked
IGreeter
service using a mock object framework, such as Moq. A mocked object is a fabricated object with a predetermined set of property and method behaviors used for testing. For more information, see xref:test/integration-tests#introduction-to-integration-tests.
Unit test gRPC services
A unit test library can directly test gRPC services by calling its methods. Unit tests test a gRPC service in isolation.
The preceding unit test:
- Mocks
IGreeter
using Moq. - Executes the
SayHelloUnary
method with a request message and aServerCallContext
. All service methods have aServerCallContext
argument. In this test, the type is provided using theTestServerCallContext.Create()
helper method. This helper method is included in the sample code. - Makes assertions:
- Verifies the request name is passed to
IGreeter
. - The service returns the expected reply message.
- Verifies the request name is passed to
Unit test HttpContext
in gRPC methods
gRPC methods can access a request's xref:Microsoft.AspNetCore.Http.HttpContext using the ServerCallContext.GetHttpContext
extension method. To unit test a method that uses HttpContext
, the context must be configured in test setup. If xref:Microsoft.AspNetCore.Http.HttpContext isn't configured then GetHttpContext
returns null
.
To configure a HttpContext
during test setup, create a new instance and add it to ServerCallContext.UserState
collection using the __HttpContext
key.
var httpContext = new DefaultHttpContext();
var serverCallContext = TestServerCallContext.Create();
serviceCallContext.UserState["__HttpContext"] = httpContext;
Execute service methods with this call context to use the configured HttpContext
instance.
Integration test gRPC services
Integration tests evaluate an app's components on a broader level than unit tests. The gRPC app is hosted in xref:Microsoft.AspNetCore.TestHost.TestServer, an in-memory test server from the Microsoft.AspNetCore.TestHost
package.
A unit test library starts the gRPC app and then gRPC services are tested using the gRPC client.
The sample code contains infrastructure to make integration testing possible:
- The
GrpcTestFixture<TStartup>
class configures the ASP.NET Core host and starts the gRPC app in an in-memory test server. - The
IntegrationTestBase
class is the base type that integration tests inherit from. It contains the fixture state and APIs for creating a gRPC client to call the gRPC app.
The preceding integration test:
- Creates a gRPC client using the channel provided by
IntegrationTestBase
. This type is included in the sample code. - Calls the
SayHelloUnary
method using the gRPC client. - Asserts the service returns the expected reply message.
Inject mock dependencies
Use ConfigureWebHost
on the fixture to override dependencies. Overriding dependencies is useful when an external dependency is unavailable in the test environment. For example, an app that uses an external payment gateway shouldn't call the external dependency when executing tests. Instead, use a mock gateway for the test.
The preceding integration test:
- In the test class's (
MockedGreeterServiceTests
) constructor:- Mocks
IGreeter
using Moq. - Overrides the
IGreeter
registered with dependency injection usingConfigureWebHost
.
- Mocks
- Calls the
SayHelloUnary
method using the gRPC client. - Asserts the expected reply message based on the mock
IGreeter
instance.