agentskills.codes
MI

migration-unit-testing

|

Install

mkdir -p .claude/skills/migration-unit-testing && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15876" && unzip -o skill.zip -d .claude/skills/migration-unit-testing && rm skill.zip

Installs to .claude/skills/migration-unit-testing

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Unit testing patterns for validating migrated applications. **Use when:** Creating tests to verify migration correctness and prevent regressions. **Triggers on:** Test creation requests, validation phase, post-migration verification. **Covers:** xUnit/NUnit for .NET, JUnit 5 for Java, mocking strategies, test organization patterns.
333 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)

About this skill

Migration Unit Testing Skill

Use this skill when creating unit tests to validate migrated applications work correctly after modernization.

When to Use This Skill

  • Creating tests to validate migration correctness
  • Building test suites for migrated .NET or Java applications
  • Implementing equivalence testing (old vs new behavior)
  • Setting up mocking for external dependencies
  • Creating regression tests for business logic
  • Establishing test coverage baselines

Testing Strategy for Migrated Applications

Priority Order

  1. Business Logic - Critical calculations, validations, workflows
  2. Data Access - Repository operations, query correctness
  3. API Endpoints - Request/response contracts, status codes
  4. Authentication/Authorization - Security flows
  5. Integrations - External service interactions
  6. UI Components - View models, presentation logic

Coverage Goals

Code AreaMinimum CoverageTarget Coverage
Business logic80%90%+
API controllers70%85%
Data access60%80%
Utilities/helpers70%90%

.NET Testing Patterns (xUnit)

Project Setup

<!-- Tests.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <IsPackable>false</IsPackable>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
    <PackageReference Include="xunit" Version="2.6.2" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.4" />
    <PackageReference Include="Moq" Version="4.20.70" />
    <PackageReference Include="FluentAssertions" Version="6.12.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.0" />
  </ItemGroup>
</Project>

Test Naming Convention

MethodName_Scenario_ExpectedBehavior

Examples:

  • GetUser_WithValidId_ReturnsUser
  • CreateOrder_WithInvalidItems_ThrowsValidationException
  • CalculateDiscount_WhenTotalExceeds100_Returns10Percent

Service Layer Test

public class UserServiceTests
{
    private readonly Mock<IUserRepository> _repositoryMock;
    private readonly Mock<ILogger<UserService>> _loggerMock;
    private readonly UserService _sut; // System Under Test
    
    public UserServiceTests()
    {
        _repositoryMock = new Mock<IUserRepository>();
        _loggerMock = new Mock<ILogger<UserService>>();
        _sut = new UserService(_repositoryMock.Object, _loggerMock.Object);
    }
    
    [Fact]
    public async Task GetByIdAsync_WithExistingUser_ReturnsUser()
    {
        // Arrange
        var expectedUser = new User { Id = 1, Name = "John Doe", Email = "[email protected]" };
        _repositoryMock
            .Setup(r => r.GetByIdAsync(1))
            .ReturnsAsync(expectedUser);
        
        // Act
        var result = await _sut.GetByIdAsync(1);
        
        // Assert
        result.Should().NotBeNull();
        result.Should().BeEquivalentTo(expectedUser);
    }
    
    [Fact]
    public async Task GetByIdAsync_WithNonExistingUser_ReturnsNull()
    {
        // Arrange
        _repositoryMock
            .Setup(r => r.GetByIdAsync(It.IsAny<int>()))
            .ReturnsAsync((User?)null);
        
        // Act
        var result = await _sut.GetByIdAsync(999);
        
        // Assert
        result.Should().BeNull();
    }
    
    [Theory]
    [InlineData("")]
    [InlineData(" ")]
    [InlineData(null)]
    public async Task CreateAsync_WithInvalidName_ThrowsArgumentException(string? invalidName)
    {
        // Arrange
        var dto = new CreateUserDto(invalidName!, "[email protected]");
        
        // Act
        var act = () => _sut.CreateAsync(dto);
        
        // Assert
        await act.Should().ThrowAsync<ArgumentException>()
            .WithMessage("*name*");
    }
}

Controller Integration Test

public class UsersControllerTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;
    private readonly WebApplicationFactory<Program> _factory;
    
    public UsersControllerTests(WebApplicationFactory<Program> factory)
    {
        _factory = factory.WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                // Replace real DB with in-memory
                var descriptor = services.SingleOrDefault(
                    d => d.ServiceType == typeof(DbContextOptions<AppDbContext>));
                if (descriptor != null)
                    services.Remove(descriptor);
                
                services.AddDbContext<AppDbContext>(options =>
                    options.UseInMemoryDatabase("TestDb"));
            });
        });
        _client = _factory.CreateClient();
    }
    
    [Fact]
    public async Task GetUsers_ReturnsSuccessAndCorrectContentType()
    {
        // Act
        var response = await _client.GetAsync("/api/users");
        
        // Assert
        response.EnsureSuccessStatusCode();
        response.Content.Headers.ContentType?.MediaType.Should().Be("application/json");
    }
    
    [Fact]
    public async Task GetUser_WithInvalidId_ReturnsNotFound()
    {
        // Act
        var response = await _client.GetAsync("/api/users/99999");
        
        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.NotFound);
    }
    
    [Fact]
    public async Task CreateUser_WithValidData_ReturnsCreatedWithLocation()
    {
        // Arrange
        var newUser = new { Name = "Jane Doe", Email = "[email protected]" };
        var content = new StringContent(
            JsonSerializer.Serialize(newUser),
            Encoding.UTF8,
            "application/json");
        
        // Act
        var response = await _client.PostAsync("/api/users", content);
        
        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.Created);
        response.Headers.Location.Should().NotBeNull();
    }
}

Database Test with In-Memory Provider

public class UserRepositoryTests : IDisposable
{
    private readonly AppDbContext _context;
    private readonly UserRepository _sut;
    
    public UserRepositoryTests()
    {
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;
        _context = new AppDbContext(options);
        _sut = new UserRepository(_context);
    }
    
    [Fact]
    public async Task AddAsync_AddsUserToDatabase()
    {
        // Arrange
        var user = new User { Name = "Test User", Email = "[email protected]" };
        
        // Act
        await _sut.AddAsync(user);
        await _context.SaveChangesAsync();
        
        // Assert
        var savedUser = await _context.Users.FirstOrDefaultAsync(u => u.Email == "[email protected]");
        savedUser.Should().NotBeNull();
        savedUser!.Name.Should().Be("Test User");
    }
    
    public void Dispose() => _context.Dispose();
}

Java Testing Patterns (JUnit 5)

Project Setup (pom.xml)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Service Layer Test

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    
    @Mock
    private UserRepository userRepository;
    
    @InjectMocks
    private UserService userService;
    
    @Test
    @DisplayName("Should return user when valid ID provided")
    void findById_WithValidId_ReturnsUser() {
        // Given
        User expectedUser = new User(1L, "John Doe", "[email protected]");
        when(userRepository.findById(1L)).thenReturn(Optional.of(expectedUser));
        
        // When
        Optional<User> result = userService.findById(1L);
        
        // Then
        assertThat(result)
            .isPresent()
            .hasValueSatisfying(user -> {
                assertThat(user.getName()).isEqualTo("John Doe");
                assertThat(user.getEmail()).isEqualTo("[email protected]");
            });
    }
    
    @Test
    @DisplayName("Should return empty when user not found")
    void findById_WithNonExistingId_ReturnsEmpty() {
        // Given
        when(userRepository.findById(anyLong())).thenReturn(Optional.empty());
        
        // When
        Optional<User> result = userService.findById(999L);
        
        // Then
        assertThat(result).isEmpty();
    }
    
    @ParameterizedTest
    @NullAndEmptySource
    @ValueSource(strings = {" ", "   "})
    @DisplayName("Should throw exception for invalid name")
    void create_WithInvalidName_ThrowsException(String invalidName) {
        // Given
        CreateUserDto dto = new CreateUserDto(invalidName, "[email protected]");
        
        // When/Then
        assertThatThrownBy(() -> userService.create(dto))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("name");
    }
}

Controller Integration Test

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIntegrationTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Test
    @DisplayName("GET /api/users sho

---

*Content truncated.*

Search skills

Search the agent skills registry