統合テストを通してエンドポイントを呼び出す方法
それは素晴らしいときにすべてのユニットテストの緑の看板をどこに戻っている.それでも、プロジェクトを実行すると、インフラ設定が間違っているため、エラーが発生しますWeb API 適切に😑. それはあなたのログ、データベース、プロバイダ、よく、他の多くのものを設定する方法です.それを修正するか、その影響を最小にする1つのアプローチは、統合テストを通してあります.それで、どのように、あなたはそれのために速いセットアップをすることができますか🤔? ところで、このブログ記事では、次のような技術を検討します. .NET Core 5 xUnit.net Moq
以下はサンプルフローを示すイメージです.
3つのステップから構成されます. ユーザーはエンドポイント/API/V 1/ムービーを呼び出します. アプリケーションは偽の処理を行います. ランダムなムービーは、ユーザーに返されます. このビジネスルールを管理するには、以下のコントローラを使います.
ここでは、ランダムなムービーを返すサービスに関する単純な単体テストを行います.次のように書くことができます.
エンドポイントをコールするには、class fixture …の助けを得てWebApplicationFactory より詳しい情報はsection Basic tests with the default WebApplicationFactory インIntegration tests in ASP.NET Core ガイド.クラスのテストコンストラクタでは、ファクトリを使用してHttpClientを作成することができます.また、注入されたサービスをモックと交換したいとしましょう
私は、あなたが最初に言ったように、あなたのコードがインフラストラクチャ層で予想通りに出荷されることをほとんど保証することができるので、時々、安い統合テストをすることから大きな利益を得ることができると思います.この記事では、いくぶん単純な例をあげましたが、物事はより挑戦的でありえます、ブローカー接続に関しては😜.
あなたは、私がここで示したコードに相談することができますthis GitHub repository . あなたはDockerを使用することができますrun the project だけでなくexecute its tests . チェックするREADME 詳細は
聴聞会.
サンプルプロジェクトの説明
以下はサンプルフローを示すイメージです.
3つのステップから構成されます.
[ApiController]
[Route("api/v1/[controller]")]
public class MoviesController : ControllerBase
{
private readonly IFilmSpecialist _filmSpecialist;
public MoviesController(IFilmSpecialist filmSpecialist)
{
_filmSpecialist = filmSpecialist;
}
[HttpGet]
public Movie Get()
{
Log.Information("Let me ask the film specialist...");
var movie = _filmSpecialist.SuggestSomeMovie();
Log.Information("Suggested movie: {Movie}", movie);
return movie;
}
}
誰が偽の処理を行う責任があります.public class FilmSpecialist : IFilmSpecialist
{
private static readonly Movie[] Films =
{
new("RoboCop", "10/08/1987", new[] {"Action", "Thriller", "Science Fiction"}, "1h 42m"),
new("The Matrix", "05/21/1999", new[] {"Action", "Science Fiction"}, "2h 16m"),
new("Soul", "12/25/2020", new[] {"Family", "Animation", "Comedy", "Drama", "Music", "Fantasy"}, "1h 41m"),
new("Space Jam", "12/25/1996", new[] {"Adventure", "Animation", "Comedy", "Family"}, "1h 28m"),
new("Aladdin", "07/03/1993", new[] {"Animation", "Family", "Adventure", "Fantasy", "Romance"}, "1h 28m"),
new("The World of Dragon Ball Z", "01/21/2000", new[] {"Action"}, "20m"),
};
public Movie SuggestSomeMovie()
{
Log.Debug("OKAY! Which film will I suggest 🤔");
Random random = new();
var filmIndexThatIWillSuggest = random.Next(0, Films.Length);
Log.Information("Will suggest the film with index {FilmIndex}!", filmIndexThatIWillSuggest);
return Films[filmIndexThatIWillSuggest];
}
}
最初に、我々のメソッド契約が尊重されていることを保証するために、単位テストをしましょう.単体テストからの起動
ここでは、ランダムなムービーを返すサービスに関する単純な単体テストを行います.次のように書くことができます.
public class FilmSpecialistTests
{
private readonly IFilmSpecialist _filmSpecialist = new FilmSpecialist();
[Fact]
public void ShouldReturnRandomMovieWhenAsked()
{
// Act
var suggestedMovie = _filmSpecialist.SuggestSomeMovie();
// Assert
var expectedTiles = new[]
{
"RoboCop", "The Matrix", "Soul", "Space Jam", "Aladdin", "The World of Dragon Ball Z"
};
suggestedMovie.Title.Should().BeOneOf(expectedTiles);
}
}
APIへの実際のHTTPリクエストの作成
エンドポイントをコールするには、class fixture …の助けを得てWebApplicationFactory より詳しい情報はsection Basic tests with the default WebApplicationFactory インIntegration tests in ASP.NET Core ガイド.クラスのテストコンストラクタでは、ファクトリを使用してHttpClientを作成することができます.また、注入されたサービスをモックと交換したいとしましょう
ConfigureTestServices
. 完全な例を示します.public class MoviesControllerITests : IClassFixture<WebApplicationFactory<Startup>>
{
private readonly IFilmSpecialist _filmSpecialist;
private HttpClient _httpClient;
public MoviesControllerITests(WebApplicationFactory<Startup> factory)
{
_filmSpecialist = Mock.Of<IFilmSpecialist>();
_httpClient = factory.WithWebHostBuilder(builder =>
{
// https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-5.0#inject-mock-services
builder.ConfigureTestServices(services =>
{
services.RemoveAll<IFilmSpecialist>();
services.TryAddTransient(_ => _filmSpecialist);
});
}).CreateClient();
}
[Fact]
public async Task ShouldCreateGameGivenFirstMovementIsBeingExecuted()
{
// Arrange
var requestPath = "/api/v1/movies";
var movieToBeSuggested = new Movie("Schindler's List", "12/31/1993", new[] {"Drama", "History", "War"}, "3h 15m");
Mock.Get(_filmSpecialist)
.Setup(f => f.SuggestSomeMovie())
.Returns(movieToBeSuggested)
.Verifiable();
// Act
var response = await _httpClient.GetAsync(requestPath);
response.StatusCode.Should().Be(HttpStatusCode.OK);
var movie = await response.Content.ReadFromJsonAsync<Movie>();
// Assert
movie.Should().BeEquivalentTo(movieToBeSuggested);
Mock.Get(_filmSpecialist).Verify();
}
}
ところで、使用にWebApplicationFactory
, パッケージをインストールする必要があります.Microsoft.AspNetCore.Mvc.Testing
それはかなり簡単です🤗. 私はそれをそのまま残します、しかし、我々は我々の統合テストを抽象化することができました😏.物事を終わらせる
私は、あなたが最初に言ったように、あなたのコードがインフラストラクチャ層で予想通りに出荷されることをほとんど保証することができるので、時々、安い統合テストをすることから大きな利益を得ることができると思います.この記事では、いくぶん単純な例をあげましたが、物事はより挑戦的でありえます、ブローカー接続に関しては😜.
あなたは、私がここで示したコードに相談することができますthis GitHub repository . あなたはDockerを使用することができますrun the project だけでなくexecute its tests . チェックするREADME 詳細は
聴聞会.
Reference
この問題について(統合テストを通してエンドポイントを呼び出す方法), 我々は、より多くの情報をここで見つけました https://dev.to/willianantunes/c-web-api-how-to-call-your-endpoint-through-integration-tests-li1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol