इकाई परीक्षण Umami.नेट - परीक्षण UmamClient (हिन्दी (Hindi))

इकाई परीक्षण Umami.नेट - परीक्षण UmamClient

Sunday, 01 September 2024

//

7 minute read

परिचय

अब मेरे पास उमामी.Net पैकेज वहाँ मैं निश्चित रूप से यह सुनिश्चित करना चाहता हूँ कि सभी अपेक्षित रूप में काम करता है नोट: यह एक 'perfect दृष्टिकोण नहीं है। ' टाइप पोस्ट है। IHttpMessageHandler यहाँ एक आप इस करने के लिए एक सामान्य HttpClient को DelegatingMessageHandler पर हमला कर सकते हैं

इकाई परीक्षण

इकाई परीक्षण को कोड के अलग-अलग इकाइयों का परीक्षण करने की प्रक्रिया निर्दिष्ट करता है ताकि यह सुनिश्चित किया जा सके कि वे अपेक्षित रूप से काम करते हैं।

Umami.Net जैसे पैकेज के लिए यह बहुत जटिल है क्योंकि यह दोनों दूरस्थ क्लाइंट पर कॉल करता है HttpClient और एक है IHostedService यह नए घटना डेटा के भेजने को यथासंभव सीधा बनाता है

UmamiClient का परीक्षण कर रहा है

एक परीक्षण का मुख्य भाग HttpClient आधारित लाइब्रेरी वास्तविक 'HttpClient' कॉल से बचता है HttpClient जो एक का उपयोग करता है HttpMessageHandler जो एक ज्ञात प्रतिक्रिया लौटाता है. यह एक बनाने के द्वारा किया जाता है HttpClient के साथ HttpMessageHandler जो एक ज्ञात प्रतिक्रिया को लौटाता है; इस मामले में मैं सिर्फ इनपुट प्रतिक्रिया के पीछे प्रतिध्वनित करता हूँ और यह जाँचें कि UmamiClient.

    public static HttpMessageHandler Create()
    {
        var mockHandler = new Mock<HttpMessageHandler>();

        mockHandler.Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.Is<HttpRequestMessage>(x => x.RequestUri.ToString().Contains("api/send")),
                ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync((HttpRequestMessage request, CancellationToken cancellationToken) =>
            {
                // Read the request content
                var requestBody = request.Content != null
                    ? request.Content.ReadAsStringAsync(cancellationToken).Result
                    : null;

                // Create a response that echoes the request body
                var responseContent = requestBody != null
                    ? requestBody
                    : "No request body";


                // Return the response
                return new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(responseContent, Encoding.UTF8, "application/json")
                };
            });

        return mockHandler.Object;
    }

जैसा कि आप ' देखेंगे यह एक सेटअप करता है Mock<HttpMessageHandler> मैं फिर में गुजरता हूँ UmamiClient. इस कोड में मैं यह हमारे IServiceCollection सेटअप विधि. यह सभी सेवाओं द्वारा आवश्यक जोड़ता है UmamiClient हमारे नए सहित HttpMessageHandler और फिर वापस करता है IServiceCollection परीक्षणों में उपयोग के लिए

    public static IServiceCollection SetupServiceCollection(string webSiteId = Consts.WebSiteId,
        string umamiPath = Consts.UmamiPath, HttpMessageHandler? handler = null)
    {
        var services = new ServiceCollection();
        var umamiClientSettings = new UmamiClientSettings
        {
            WebsiteId = webSiteId,
            UmamiPath = umamiPath
        };
        services.AddSingleton(umamiClientSettings);
        services.AddScoped<PayloadService>();
        services.AddLogging(x => x.AddConsole());
        // Mocking HttpMessageHandler with Moq
        var mockHandler = handler ?? EchoMockHandler.Create();
        services.AddHttpClient<UmamiClient>((serviceProvider, client) =>
        {
            var umamiSettings = serviceProvider.GetRequiredService<UmamiClientSettings>();
            client.BaseAddress = new Uri(umamiSettings.UmamiPath);
        }).ConfigurePrimaryHttpMessageHandler(() => mockHandler);
        return services;
    }

इस का उपयोग करने के लिए और इसे इंजेक्शन में UmamiClient तब मैं इन सेवाओं का उपयोग कर रहा हूँ UmamiClient सेटअप

    public static UmamiClient GetUmamiClient(IServiceCollection? serviceCollection = null,
        HttpContextAccessor? contextAccessor = null)
    {
        serviceCollection ??= SetupServiceCollection();
        SetupUmamiClient(serviceCollection, contextAccessor);
        if (serviceCollection == null) throw new NullReferenceException(nameof(serviceCollection));
        var serviceProvider = serviceCollection.BuildServiceProvider();
        return serviceProvider.GetRequiredService<UmamiClient>();
    }

You'll see I have a bunch of alternative optional parameters here allowing me to inject different options for different test types

टेस्ट्स

तो अब मैं सभी इस सेटअप जगह पर है मैं अब के लिए परीक्षण लिखना शुरू कर सकता हूँ UmamiClient विधि

भेजें (S)

क्या यह सब सेटअप का मतलब है कि हमारे परीक्षण वास्तव में काफी सरल हो सकता है

public class UmamiClient_SendTests
{
    [Fact]
    public async Task Send_Wrong_Type()
    {
        var umamiClient = SetupExtensions.GetUmamiClient();
        await Assert.ThrowsAsync<ArgumentException>(async () => await umamiClient.Send(type: "boop"));
    }

    [Fact]
    public async Task Send_Empty_Success()
    {
        var umamiClient = SetupExtensions.GetUmamiClient();
        var response = await umamiClient.Send();
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

यहाँ आप देख सकते हैं कि सरलतम परीक्षण मामला-, सिर्फ सुनिश्चित करने के लिए UmamiClient एक संदेश भेज सकते हैं और एक प्रतिक्रिया प्राप्त कर सकता है type गलत है

पृष्ठ दृश्य

हमारे पृष्ठ दृश्य विधि का परीक्षण करने के लिए हम कुछ ऐसा कर सकते हैं EchoHttpHandler सिर्फ भेजे गए प्रतिक्रिया को प्रतिबिंबित करने के लिए और यह सुनिश्चित करता है कि वह वापस भेजता है क्या मैं आशा करता हूँ

    [Fact]
    public async Task TrackPageView_WithNoUrl()
    {
        var defaultUrl = "/testpath";
        var contextAccessor = SetupExtensions.SetupHttpContextAccessor(path: "/testpath");
        var umamiClient = SetupExtensions.GetUmamiClient(contextAccessor: contextAccessor);
        var response = await umamiClient.TrackPageView();

        var content = await response.Content.ReadFromJsonAsync<EchoedRequest>();
        Assert.NotNull(response);
        Assert.NotNull(content);
        Assert.Equal(content.Payload.Url, defaultUrl);
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }

HttpContextAccessor

यह उपयोग करता है HttpContextAccessor पथ को सेट करने के लिए /testpath और फिर जाँच करता है कि UmamiClient यह सही रूप से भेजता है.

    public static HttpContextAccessor SetupHttpContextAccessor(string host = Consts.Host,
        string path = Consts.Path, string ip = Consts.Ip, string userAgent = Consts.UserAgent,
        string referer = Consts.Referer)
    {
        HttpContext httpContext = new DefaultHttpContext();
        httpContext.Request.Host = new HostString(host);
        httpContext.Request.Path = new PathString(path);
        httpContext.Connection.RemoteIpAddress = IPAddress.Parse(ip);
        httpContext.Request.Headers.UserAgent = userAgent;
        httpContext.Request.Headers.Referer = referer;

        var context = new HttpContextAccessor { HttpContext = httpContext };
        return context;
    }

यह हमारे उमामी क्लाइंट कोड के लिए महत्वपूर्ण है क्योंकि प्रत्येक अनुरोध से भेजे गए डेटा का अधिकांश वास्तव में गतिशील रूप से उत्पन्न किया जाता है HttpContext वस्तु. तो हम एक में कुछ भी नहीं भेज सकते await umamiClient.TrackPageView(); कॉल और यह अभी भी सही डेटा Url से बाहर निकाल कर भेजेगा HttpContext.

जैसा कि हम ''' बाद में देखेंगे यह''' भी महत्वपूर्ण है आश्चर्य के समान वस्तुओं को भेजने UserAgent और IPAddress चूंकि इन का उपयोग Umami सर्वर द्वारा डेटा और 'trackM SK1 उपयोगकर्ता दृश्य को बिना कुकीज़ के ट्रैक करने के लिए किया जाता है

इस पूर्वानुमानीय होने के लिए हम में एक समूह के कंस्ट परिभाषित करें Consts वर्ग. तो हम अनुमानित प्रतिक्रियाओं और अनुरोधों के विरुद्ध परीक्षण कर सकते हैं

public class Consts
{
    public const string UmamiPath = "https://example.com";
    public const string WebSiteId = "B41A9964-FD33-4108-B6EC-9A6B68150763";
    public const string Host = "example.com";
    public const string Path = "/example";
    public const string Ip = "127.0.0.1";
    public const string UserAgent = "Test User Agent";
    public const string Referer = "Test Referer";
    public const string DefaultUrl = "/testpath";
    public const string DefaultTitle = "Example Page";
    public const string DefaultName = "RSS";
    public const string DefaultType = "event";

    public const string Email = "[email protected]";

    public const string UserId = "11224456";
    
    public const string UserName = "Test User";
    
    public const string SessionId = "B41A9964-FD33-4108-B6EC-9A6B68150763";
}

और परीक्षण

हम अभी भी परीक्षण करने के लिए है Umami के लिए परीक्षण रणनीति का सिर्फ शुरू है IHostedService और वास्तविक डेटा के विरुद्ध परीक्षण Umami उत्पन्न करता है (जो कोई भी documented नहीं है, लेकिन कुछ उपयोगी डाटा के साथ एक JWT टोकन है

{
  "alg": "HS256",
  "typ": "JWT"
}{
  "id": "b9836672-feee-55c5-985a-a5a23d4a23ad",
  "websiteId": "32c2aa31-b1ac-44c0-b8f3-ff1f50403bee",
  "hostname": "example.com",
  "browser": "chrome",
  "os": "Windows 10",
  "device": "desktop",
  "screen": "1920x1080",
  "language": "en-US",
  "country": "GB",
  "subdivision1": null,
  "subdivision2": null,
  "city": null,
  "createdAt": "2024-09-01T09:26:14.418Z",
  "visitId": "e7a6542f-671a-5573-ab32-45244474da47",
  "iat": 1725182817
}2|Y*: �(N%-ޘ^1>@V

तो हम यह करने के लिए परीक्षण करना चाहते हैं कि ' , टोकन सिमुलित करें और संभवतः प्रत्येक दौर पर डेटा लौटाना है। uuid(websiteId,ipaddress, useragent)).

अंत में

यह सिर्फ Umami के परीक्षण का प्रारंभ है। . नेट पैकेज।

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.