برنامه نویسی

آزمایش حداقل API های وب با ASP.NET: راهنمای توسعه دهنده

نوشتن تست برای API های وب همیشه سرگرم کننده نیست ، اما لازم نیست سخت باشد. در این راهنما ، من به شما نشان می دهم که چگونه می توانید تست های ادغام تمیز و مؤثر را برای یک API وب حداقل ASP.NET بنویسید ، و یک نقطه شروع محکم برای ساخت آن به شما می دهد. 💡


تنظیم مرحله 🛠

قبل از اینکه به آزمایش بپردازیم ، برای آزمایش به API نیاز داریم. ما آن را ساده نگه می داریم – موجودی کتاب با ذخیره سازی حافظه. بدون بانک اطلاعاتی ، بدون چارچوب سنگین ، فقط یک API حداقل ASP.NET تمیز.

این دستورات را برای تنظیم راه حل خود اجرا کنید:

dotnet new sln --name BooksInventory

mkdir src tests
dotnet new web -o src/BooksInventory.WebApi
dotnet new xunit -o tests/BooksInventory.WebApi.Tests

dotnet sln add src/BooksInventory.WebApi
dotnet sln add tests/BooksInventory.WebApi.Tests

dotnet add tests/BooksInventory.WebApi.Tests package FluentAssertions
dotnet add tests/BooksInventory.WebApi.Tests package Microsoft.AspNetCore.Mvc.Testing
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


درک API موجودی کتاب

API دو نقطه پایانی را ارائه می دهد:

  • پست /addBook: بار json را با آن می پذیرد Titleبا Authorوت ISBN، آن را ذخیره می کند ، و یک منحصر به فرد را برمی گرداند BookIdبشر
  • بدست آوردن /books/{id}: جزئیات کتاب را با استفاده از BookIdبشر

در اینجا API ما است Program.cs:

using System.Collections.Concurrent;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

var books = new ConcurrentDictionary<string, Book>();

app.MapPost("/addBook", (AddBookRequest request) =>
{
    var bookId = Guid.NewGuid().ToString();
    var book = new Book(request.Title, request.Author, request.ISBN);

    if (!books.TryAdd(bookId, book))
    {
        return Results.Problem("Failed to add book due to a concurrency issue.");
    }

    return Results.Ok(new AddBookResponse(bookId));
});

app.MapGet("/books/{id}", (string id) =>
{
    if (books.TryGetValue(id, out var book))
    {
        return Results.Ok(book);
    }
    return Results.NotFound(new { Message = "Book not found", BookId = id });
});

app.Run();

public record AddBookRequest(string Title, string Author, string ISBN);
public record AddBookResponse(string BookId);
public record Book(string Title, string Author, string ISBN);

// Explicitly define Program as partial for integration tests
public partial class Program { }
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


نوشتن تست های ادغام

ما استفاده خواهیم کرد زونبا WebApplicatoryوت سرنوشتبشر

در اینجا پرونده تست ما است ، BookInventoryTests.cs:

using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;

namespace BooksInventory.WebApi.Tests;

public class BookInventoryTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;

    public BookInventoryTests(WebApplicationFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task AddBook_ReturnsBookId()
    {
        var request = new AddBookRequest("AI Engineering", "Chip Huyen", "1098166302");
        var content = request.GetHttpContent();

        var response = await _client.PostAsync("/addBook", content);

        response.EnsureSuccessStatusCode();
        var result = await response.DeserializeAsync<AddBookResponse>();
        result?.Should().NotBeNull();
        result!.BookId.Should().NotBeNullOrEmpty();
    }

    [Fact]
    public async Task GetBook_ReturnsBookDetails()
    {
        var addRequest = new AddBookRequest("AI Engineering", "Chip Huyen", "1234567890");
        var addResponse = await _client.PostAsync("/addBook", addRequest.GetHttpContent());
        var bookId = (await addResponse.DeserializeAsync<AddBookResponse>())?.BookId;

        var getResponse = await _client.GetAsync($"/books/{bookId}");

        getResponse.EnsureSuccessStatusCode();
        var book = await getResponse.DeserializeAsync<Book>();
        book.Should().BeEquivalentTo(
            new Book(
                addRequest.Title,
                addRequest.Author,
                addRequest.ISBN));
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


آن را تمیز نگه دارید: روشهای پسوند قابل استفاده مجدد

آزمایش باید آسان باشد ، پر از کد مکرر برای سریال سازی و deserialization. بیایید با برخی از روش های یاور کارها را تمیز کنیم.

using System.Text;
using System.Text.Json;

public static class HttpContentExtensions
{
    private static readonly JsonSerializerOptions SerializerOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    public static async Task<T?> DeserializeAsync<T>(this HttpResponseMessage response)
    {
        return JsonSerializer.Deserialize<T>(
            await response.Content.ReadAsStringAsync(),
            SerializerOptions);
    }

    public static HttpContent GetHttpContent<T>(this T obj) where T : class
    {
        return new StringContent(
            JsonSerializer.Serialize(obj),
            Encoding.UTF8, "application/json");
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


تست دستی (برای زمانی که فقط می خواهید روی یک دکمه کلیک کنید)

بعضی اوقات ، شما فقط می خواهید یک API را بدون نوشتن یک مورد آزمایش آزمایش کنید. این جایی است که Client Ret in VS Code وارد می شود. ایجاد کنید .http پرونده مانند این:

POST {{baseUrl}}/addBook HTTP/1.1
Content-Type: application/json

{
    "Title": "The Pragmatic Programmer",
    "Author": "Andy Hunt and Dave Thomas",
    "ISBN": "9780135957059"
}

###

# Test GET /books/{id} (replace {id} with a valid BookId from the POST response)
GET {{baseUrl}}/books/{id} HTTP/1.1
Accept: application/json
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سپس درخواست ها را درست در داخل VS Code اجرا کنید. هیچ پستچی لازم نیست. 😎


بسته بندی: تست ادغام برای API های وب می تواند سرگرم کننده باشد

آزمایش ASP.NET حداقل API های وب لازم نیست یک تجربه دردناک باشد. ما همه چیز را سبک نگه داشتیم:

  • مورد استفاده WebApplicationFactory برای تست های ادغام به جای مسخره کردن همه چیز. 🔧
  • از دیگ بخار آزمایشی خودداری کرد FluentAssertions و روشهای پسوند 💅
  • اهرم مشتری استراحت برای آزمایش سریع دستی. ⚡

این رویکرد را در پروژه های خود امتحان کنید و ببینید که گردش کار آزمایش شما چقدر نرم تر می شود. یک ترفند آزمایشی جالب دارید؟ آن را در نظرات به اشتراک بگذارید یا من را در GitHub در اینجا قرار دهید. 📬

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا