Notification Postman API testing in dotnet core…



This content originally appeared on DEV Community and was authored by Yogesh Baghel

To test your notification system backend before implementing the frontend, you can use several approaches. Here are the most effective methods

1. API Testing with Postman/Insomnia

Create a collection to test all endpoints:

{
  "info": {
    "name": "Notification API Tests",
    "description": "Test collection for notification endpoints"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{jwt_token}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "Create Notification",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"userId\": 1,\n  \"title\": \"Test Notification\",\n  \"urlt\": \"https://example.com\",\n  \"message\": \"This is a test notification\",\n  \"sipid\": 123\n}"
        },
        "url": {
          "raw": "{{base_url}}/api/notifications",
          "host": ["{{base_url}}"],
          "path": ["api", "notifications"]
        }
      }
    },
    {
      "name": "Get Notifications",
      "request": {
        "method": "GET",
        "url": {
          "raw": "{{base_url}}/api/notifications?page=1&pageSize=10",
          "host": ["{{base_url}}"],
          "path": ["api", "notifications"],
          "query": [
            {
              "key": "page",
              "value": "1"
            },
            {
              "key": "pageSize",
              "value": "10"
            }
          ]
        }
      }
    },
    {
      "name": "Get Unread Count",
      "request": {
        "method": "GET",
        "url": {
          "raw": "{{base_url}}/api/notifications/unread-count",
          "host": ["{{base_url}}"],
          "path": ["api", "notifications", "unread-count"]
        }
      }
    },
    {
      "name": "Mark as Read",
      "request": {
        "method": "PUT",
        "url": {
          "raw": "{{base_url}}/api/notifications/1/read",
          "host": ["{{base_url}}"],
          "path": ["api", "notifications", "1", "read"]
        }
      }
    },
    {
      "name": "Mark All as Read",
      "request": {
        "method": "PUT",
        "url": {
          "raw": "{{base_url}}/api/notifications/mark-all-read",
          "host": ["{{base_url}}"],
          "path": ["api", "notifications", "mark-all-read"]
        }
      }
    },
    {
      "name": "Delete Notification",
      "request": {
        "method": "DELETE",
        "url": {
          "raw": "{{base_url}}/api/notifications/1",
          "host": ["{{base_url}}"],
          "path": ["api", "notifications", "1"]
        }
      }
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "https://localhost:5001"
    },
    {
      "key": "jwt_token",
      "value": "your_jwt_token_here"
    }
  ]
}

2. Unit Tests

Create comprehensive unit tests for your services:

using ArimartEcommerceAPI.DTOs;
using ArimartEcommerceAPI.Infrastructure.Data.Models;
using ArimartEcommerceAPI.Repositories;
using ArimartEcommerceAPI.Services;
using Microsoft.AspNetCore.SignalR;
using Moq;
using Xunit;

namespace ArimartEcommerceAPI.Tests
{
    public class NotificationServiceTests
    {
        private readonly Mock<INotificationRepository> _mockRepository;
        private readonly Mock<IHubContext<NotificationHub>> _mockHubContext;
        private readonly NotificationService _service;

        public NotificationServiceTests()
        {
            _mockRepository = new Mock<INotificationRepository>();
            _mockHubContext = new Mock<IHubContext<NotificationHub>>();
            _service = new NotificationService(_mockRepository.Object, _mockHubContext.Object);
        }

        [Fact]
        public async Task GetNotificationsAsync_ShouldReturnSuccessResponse()
        {
            // Arrange
            var userId = 1L;
            var page = 1;
            var pageSize = 10;
            var expectedResponse = new NotificationListResponse
            {
                Notifications = new List<NotificationDto>
                {
                    new NotificationDto
                    {
                        Id = 1,
                        UserId = userId,
                        Title = "Test Notification",
                        Urlt = "https://example.com",
                        Message = "Test message",
                        Acctt = false,
                        AddedDate = DateTime.UtcNow,
                        IsActive = true
                    }
                },
                TotalCount = 1,
                CurrentPage = page,
                PageSize = pageSize,
                HasMore = false
            };

            _mockRepository.Setup(r => r.GetNotificationsAsync(userId, page, pageSize))
                         .ReturnsAsync(expectedResponse);

            // Act
            var result = await _service.GetNotificationsAsync(userId, page, pageSize);

            // Assert
            Assert.True(result.Success);
            Assert.Equal(expectedResponse, result.Data);
            Assert.Equal("Notifications retrieved successfully", result.Message);
        }

        [Fact]
        public async Task CreateNotificationAsync_ShouldCreateAndSendSignalR()
        {
            // Arrange
            var createDto = new CreateNotificationDto
            {
                UserId = 1L,
                Title = "Test Notification",
                Urlt = "https://example.com",
                Message = "Test message",
                Sipid = 123
            };

            var createdNotification = new TblNotification
            {
                Id = 1,
                UserId = createDto.UserId,
                Title = createDto.Title,
                Urlt = createDto.Urlt,
                Message = createDto.Message,
                Acctt = false,
                AddedDate = DateTime.UtcNow,
                IsActive = true,
                Sipid = createDto.Sipid
            };

            _mockRepository.Setup(r => r.CreateNotificationAsync(createDto))
                         .ReturnsAsync(createdNotification);

            var mockClients = new Mock<IHubCallerClients>();
            var mockGroup = new Mock<IClientProxy>();

            _mockHubContext.Setup(h => h.Clients).Returns(mockClients.Object);
            mockClients.Setup(c => c.Group($"user_{createDto.UserId}")).Returns(mockGroup.Object);

            // Act
            var result = await _service.CreateNotificationAsync(createDto);

            // Assert
            Assert.True(result.Success);
            Assert.NotNull(result.Data);
            Assert.Equal(createdNotification.Id, result.Data.Id);
            Assert.Equal("Notification created successfully", result.Message);

            // Verify SignalR was called
            mockGroup.Verify(g => g.SendCoreAsync("ReceiveNotification", 
                It.IsAny<object[]>(), default), Times.Once);
        }

        [Fact]
        public async Task MarkAsReadAsync_ShouldUpdateUnreadCount()
        {
            // Arrange
            var notificationId = 1L;
            var userId = 1L;
            var unreadCount = 5;

            _mockRepository.Setup(r => r.MarkAsReadAsync(notificationId, userId))
                         .ReturnsAsync(true);
            _mockRepository.Setup(r => r.GetUnreadCountAsync(userId))
                         .ReturnsAsync(unreadCount);

            var mockClients = new Mock<IHubCallerClients>();
            var mockGroup = new Mock<IClientProxy>();

            _mockHubContext.Setup(h => h.Clients).Returns(mockClients.Object);
            mockClients.Setup(c => c.Group($"user_{userId}")).Returns(mockGroup.Object);

            // Act
            var result = await _service.MarkAsReadAsync(notificationId, userId);

            // Assert
            Assert.True(result.Success);
            Assert.True(result.Data);
            Assert.Equal("Notification marked as read", result.Message);

            // Verify SignalR was called with updated count
            mockGroup.Verify(g => g.SendCoreAsync("UpdateUnreadCount", 
                It.Is<object[]>(args => args[0].Equals(unreadCount)), default), Times.Once);
        }

        [Fact]
        public async Task GetUnreadCountAsync_ShouldReturnCount()
        {
            // Arrange
            var userId = 1L;
            var expectedCount = 3;

            _mockRepository.Setup(r => r.GetUnreadCountAsync(userId))
                         .ReturnsAsync(expectedCount);

            // Act
            var result = await _service.GetUnreadCountAsync(userId);

            // Assert
            Assert.True(result.Success);
            Assert.Equal(expectedCount, result.Data);
            Assert.Equal("Unread count retrieved successfully", result.Message);
        }

        [Fact]
        public async Task MarkAllAsReadAsync_ShouldResetUnreadCount()
        {
            // Arrange
            var userId = 1L;

            _mockRepository.Setup(r => r.MarkAllAsReadAsync(userId))
                         .ReturnsAsync(true);

            var mockClients = new Mock<IHubCallerClients>();
            var mockGroup = new Mock<IClientProxy>();

            _mockHubContext.Setup(h => h.Clients).Returns(mockClients.Object);
            mockClients.Setup(c => c.Group($"user_{userId}")).Returns(mockGroup.Object);

            // Act
            var result = await _service.MarkAllAsReadAsync(userId);

            // Assert
            Assert.True(result.Success);
            Assert.True(result.Data);
            Assert.Equal("All notifications marked as read", result.Message);

            // Verify SignalR was called with count 0
            mockGroup.Verify(g => g.SendCoreAsync("UpdateUnreadCount", 
                It.Is<object[]>(args => args[0].Equals(0)), default), Times.Once);
        }

        [Fact]
        public async Task DeleteNotificationAsync_ShouldReturnSuccess()
        {
            // Arrange
            var notificationId = 1L;
            var userId = 1L;

            _mockRepository.Setup(r => r.DeleteNotificationAsync(notificationId, userId))
                         .ReturnsAsync(true);

            // Act
            var result = await _service.DeleteNotificationAsync(notificationId, userId);

            // Assert
            Assert.True(result.Success);
            Assert.True(result.Data);
            Assert.Equal("Notification deleted successfully", result.Message);
        }
    }
}

3. Simple SignalR Test Client

Create a simple console application to test SignalR:

using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;

namespace NotificationTestClient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:5001/notificationHub", options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult("your_jwt_token_here");
                })
                .Build();

            // Handle incoming notifications
            connection.On<object>("ReceiveNotification", (notification) =>
            {
                Console.WriteLine($"Received notification: {notification}");
            });

            // Handle unread count updates
            connection.On<int>("UpdateUnreadCount", (count) =>
            {
                Console.WriteLine($"Unread count updated: {count}");
            });

            try
            {
                await connection.StartAsync();
                Console.WriteLine("Connected to SignalR hub");

                // Join user group
                await connection.InvokeAsync("JoinUserGroup", "1"); // Replace with actual user ID
                Console.WriteLine("Joined user group");

                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
            finally
            {
                await connection.DisposeAsync();
            }
        }
    }
}

// Add this to your test project's .csproj file:
/*
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.0" />
  </ItemGroup>
</Project>
*/

4. Integration Tests

Create integration tests to test the entire flow:

using ArimartEcommerceAPI.DTOs;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using Xunit;

namespace ArimartEcommerceAPI.IntegrationTests
{
    public class NotificationControllerIntegrationTests : IClassFixture<WebApplicationFactory<Program>>
    {
        private readonly WebApplicationFactory<Program> _factory;
        private readonly HttpClient _client;

        public NotificationControllerIntegrationTests(WebApplicationFactory<Program> factory)
        {
            _factory = factory;
            _client = _factory.CreateClient();

            // Add authorization header for tests
            _client.DefaultRequestHeaders.Add("Authorization", "Bearer your_test_jwt_token");
        }

        [Fact]
        public async Task GetNotifications_ShouldReturnOkResponse()
        {
            // Act
            var response = await _client.GetAsync("/api/notifications?page=1&pageSize=10");

            // Assert
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<ApiResponse<NotificationListResponse>>(content);

            Assert.True(result.Success);
            Assert.NotNull(result.Data);
        }

        [Fact]
        public async Task CreateNotification_ShouldReturnCreatedNotification()
        {
            // Arrange
            var createDto = new CreateNotificationDto
            {
                UserId = 1,
                Title = "Integration Test Notification",
                Urlt = "https://example.com",
                Message = "This is an integration test",
                Sipid = 123
            };

            var json = JsonConvert.SerializeObject(createDto);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            // Act
            var response = await _client.PostAsync("/api/notifications", content);

            // Assert
            response.EnsureSuccessStatusCode();
            var responseContent = await response.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<ApiResponse<NotificationDto>>(responseContent);

            Assert.True(result.Success);
            Assert.NotNull(result.Data);
            Assert.Equal(createDto.Title, result.Data.Title);
        }

        [Fact]
        public async Task GetUnreadCount_ShouldReturnCount()
        {
            // Act
            var response = await _client.GetAsync("/api/notifications/unread-count");

            // Assert
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<ApiResponse<int>>(content);

            Assert.True(result.Success);
            Assert.True(result.Data >= 0);
        }

        [Fact]
        public async Task MarkAsRead_ShouldReturnSuccess()
        {
            // First create a notification
            var createDto = new CreateNotificationDto
            {
                UserId = 1,
                Title = "Test for Mark as Read",
                Urlt = "https://example.com",
                Message = "Test message"
            };

            var json = JsonConvert.SerializeObject(createDto);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var createResponse = await _client.PostAsync("/api/notifications", content);

            var createResult = JsonConvert.DeserializeObject<ApiResponse<NotificationDto>>(
                await createResponse.Content.ReadAsStringAsync());

            // Act - Mark as read
            var markReadResponse = await _client.PutAsync($"/api/notifications/{createResult.Data.Id}/read", null);

            // Assert
            markReadResponse.EnsureSuccessStatusCode();
            var markReadContent = await markReadResponse.Content.ReadAsStringAsync();
            var markReadResult = JsonConvert.DeserializeObject<ApiResponse<bool>>(markReadContent);

            Assert.True(markReadResult.Success);
            Assert.True(markReadResult.Data);
        }

        [Fact]
        public async Task MarkAllAsRead_ShouldReturnSuccess()
        {
            // Act
            var response = await _client.PutAsync("/api/notifications/mark-all-read", null);

            // Assert
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<ApiResponse<bool>>(content);

            Assert.True(result.Success);
            Assert.True(result.Data);
        }

        [Fact]
        public async Task DeleteNotification_ShouldReturnSuccess()
        {
            // First create a notification
            var createDto = new CreateNotificationDto
            {
                UserId = 1,
                Title = "Test for Delete",
                Urlt = "https://example.com",
                Message = "Test message"
            };

            var json = JsonConvert.SerializeObject(createDto);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var createResponse = await _client.PostAsync("/api/notifications", content);

            var createResult = JsonConvert.DeserializeObject<ApiResponse<NotificationDto>>(
                await createResponse.Content.ReadAsStringAsync());

            // Act - Delete notification
            var deleteResponse = await _client.DeleteAsync($"/api/notifications/{createResult.Data.Id}");

            // Assert
            deleteResponse.EnsureSuccessStatusCode();
            var deleteContent = await deleteResponse.Content.ReadAsStringAsync();
            var deleteResult = JsonConvert.DeserializeObject<ApiResponse<bool>>(deleteContent);

            Assert.True(deleteResult.Success);
            Assert.True(deleteResult.Data);
        }
    }
}

5. Manual Testing Steps

Here’s a step-by-step manual testing approach:
Step 1: Test Authentication

Ensure your JWT authentication is working
Get a valid JWT token for testing

Step 2: Test API Endpoints

Create notifications – Use POST /api/notifications
Get notifications – Use GET /api/notifications
Get unread count – Use GET /api/notifications/unread-count
Mark as read – Use PUT /api/notifications/{id}/read
Mark all as read – Use PUT /api/notifications/mark-all-read
Delete notification – Use DELETE /api/notifications/{id}

Step 3: Test SignalR Hub

Use the SignalR test client above
Create notifications and verify real-time updates
Test mark as read and verify unread count updates

Step 4: Test Database

Check if notifications are being stored correctly
Verify soft deletion (IsDeleted flag)
Check if read status is updating properly

6. Quick Test Script

You can also create a simple test script to automate basic testing:

# Notification API Test Script
$baseUrl = "https://localhost:5001"
$token = "your_jwt_token_here"

$headers = @{
    "Authorization" = "Bearer $token"
    "Content-Type" = "application/json"
}

# Test 1: Create Notification
Write-Host "Testing Create Notification..." -ForegroundColor Green
$createNotificationBody = @{
    userId = 1
    title = "Test Notification"
    urlt = "https://example.com"
    message = "This is a test notification"
    sipid = 123
} | ConvertTo-Json

try {
    $createResponse = Invoke-RestMethod -Uri "$baseUrl/api/notifications" -Method Post -Body $createNotificationBody -Headers $headers
    Write-Host "Create Notification: SUCCESS" -ForegroundColor Green
    Write-Host "Created notification ID: $($createResponse.data.id)" -ForegroundColor Yellow
    $notificationId = $createResponse.data.id
} catch {
    Write-Host "Create Notification: FAILED - $($_.Exception.Message)" -ForegroundColor Red
}

# Test 2: Get Notifications
Write-Host "`nTesting Get Notifications..." -ForegroundColor Green
try {
    $getResponse = Invoke-RestMethod -Uri "$baseUrl/api/notifications?page=1&pageSize=10" -Method Get -Headers $headers
    Write-Host "Get Notifications: SUCCESS" -ForegroundColor Green
    Write-Host "Total notifications: $($getResponse.data.totalCount)" -ForegroundColor Yellow
} catch {
    Write-Host "Get Notifications: FAILED - $($_.Exception.Message)" -ForegroundColor Red
}

# Test 3: Get Unread Count
Write-Host "`nTesting Get Unread Count..." -ForegroundColor Green
try {
    $countResponse = Invoke-RestMethod -Uri "$baseUrl/api/notifications/unread-count" -Method Get -Headers $headers
    Write-Host "Get Unread Count: SUCCESS" -ForegroundColor Green
    Write-Host "Unread count: $($countResponse.data)" -ForegroundColor Yellow
} catch {
    Write-Host "Get Unread Count: FAILED - $($_.Exception.Message)" -ForegroundColor Red
}

# Test 4: Mark as Read
if ($notificationId) {
    Write-Host "`nTesting Mark as Read..." -ForegroundColor Green
    try {
        $markReadResponse = Invoke-RestMethod -Uri "$baseUrl/api/notifications/$notificationId/read" -Method Put -Headers $headers
        Write-Host "Mark as Read: SUCCESS" -ForegroundColor Green
    } catch {
        Write-Host "Mark as Read: FAILED - $($_.Exception.Message)" -ForegroundColor Red
    }
}

# Test 5: Mark All as Read
Write-Host "`nTesting Mark All as Read..." -ForegroundColor Green
try {
    $markAllReadResponse = Invoke-RestMethod -Uri "$baseUrl/api/notifications/mark-all-read" -Method Put -Headers $headers
    Write-Host "Mark All as Read: SUCCESS" -ForegroundColor Green
} catch {
    Write-Host "Mark All as Read: FAILED - $($_.Exception.Message)" -ForegroundColor Red
}

# Test 6: Delete Notification
if ($notificationId) {
    Write-Host "`nTesting Delete Notification..." -ForegroundColor Green
    try {
        $deleteResponse = Invoke-RestMethod -Uri "$baseUrl/api/notifications/$notificationId" -Method Delete -Headers $headers
        Write-Host "Delete Notification: SUCCESS" -ForegroundColor Green
    } catch {
        Write-Host "Delete Notification: FAILED - $($_.Exception.Message)" -ForegroundColor Red
    }
}

Write-Host "`nAll tests completed!" -ForegroundColor Blue

Testing Order:

  • Start with Unit Tests – Test individual components in isolation
  • Run Integration Tests – Test the entire API flow
  • Use Postman/Manual Testing – Test real HTTP requests
  • Test SignalR – Use the console client to verify real-time functionality
  • Run the PowerShell script – For quick automated testing This comprehensive testing approach will ensure your notification system is working correctly before you build the frontend!


This content originally appeared on DEV Community and was authored by Yogesh Baghel