Patterns and techniques for evaluating and improving AI agent outputs.
中文简介正在准备中。当前显示原文说明。
Specialized skill for testing FluentValidation validators. Use when you need to create tests for Validator classes, validate business rules, or test error messages. Covers complete FluentValidation.TestHelper usage, ShouldHaveValidationErrorFor, async validation, cross-field logic, etc. Keywords: validator, validation, fluentvalidation, validation testing, UserValidator, CreateOrderValidator, TestHelper, ShouldHaveValidationErrorFor, ShouldNotHaveValidationErrorFor, TestValidate, TestValidateAsync, testing validators, validating business rules
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
This skill focuses on testing data validation logic using FluentValidation.TestHelper, covering basic validation, complex business rules, async validation, and testing best practices.
Validators are the first line of defense for applications, testing validators can:
<PackageReference Include="FluentValidation" Version="11.11.0" />
<PackageReference Include="FluentValidation.TestHelper" Version="11.11.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="Microsoft.Extensions.Time.Testing" Version="9.0.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="AwesomeAssertions" Version="9.1.0" />
using FluentValidation;
using FluentValidation.TestHelper;
using Microsoft.Extensions.Time.Testing;
using NSubstitute;
using Xunit;
using AwesomeAssertions;
This section covers 7 core testing patterns, each including validator definitions and complete test examples.
For complete code examples, see references/core-test-patterns.md
TestValidate + ShouldHaveValidationErrorFor /
ShouldNotHaveValidationErrorFor to test single field rules[Theory] + [InlineData] to test multiple invalid/valid input
combinationsMust() rules, and other multi-field related
validationsTimeProvider, using FakeTimeProvider to control time for
testing.When() for optional field validation, testing conditional trigger and
skip scenariosMustAsync + TestValidateAsync, using NSubstitute Mock for external servicespublic class UserValidatorTests
{
private readonly UserValidator _validator = new();
[Fact]
public void Validate_Blank_Username_Should_Validation_Fail()
{
var result = _validator.TestValidate(
new UserRegistrationRequest { Username = "" });
result.ShouldHaveValidationErrorFor(x => x.Username)
.WithErrorMessage("Username cannot be null or blank");
}
}
| Method | Purpose | Example |
|---|---|---|
TestValidate(model) | Execute sync validation | _validator.TestValidate(request) |
TestValidateAsync(model) | Execute async validation | await _validator.TestValidateAsync(request) |
| Method | Purpose | Example |
|---|---|---|
ShouldHaveValidationErrorFor(x => x.Property) | Assert property should have error | result.ShouldHaveValidationErrorFor(x => x.Username) |
ShouldNotHaveValidationErrorFor(x => x.Property) | Assert property should not have error | result.ShouldNotHaveValidationErrorFor(x => x.Email) |
ShouldNotHaveAnyValidationErrors() | Assert entire object has no errors | result.ShouldNotHaveAnyValidationErrors() |
| Method | Purpose | Example |
|---|---|---|
WithErrorMessage(string) | Validate error message content | .WithErrorMessage("Username cannot be empty") |
WithErrorCode(string) | Validate error code | .WithErrorCode("NOT_EMPTY") |
Method_Scenario_ExpectedResult format[Theory]
[InlineData("", "Email cannot be null or blank")]
[InlineData("invalid", "Email format is incorrect")]
[InlineData("@example.com", "Email format is incorrect")]
public void Validate_Invalid_Email_Should_Validation_Fail(string email, string expectedError)
{
var request = new UserRegistrationRequest { Email = email };
var result = _validator.TestValidate(request);
result.ShouldHaveValidationErrorFor(x => x.Email).WithErrorMessage(expectedError);
}
[Theory]
[InlineData(17, "Age must be greater than or equal to 18")]
[InlineData(121, "Age must be less than or equal to 120")]
public void Validate_Invalid_Age_Should_Validation_Fail(int age, string expectedError)
{
var request = new UserRegistrationRequest { Age = age };
var result = _validator.TestValidate(request);
result.ShouldHaveValidationErrorFor(x => x.Age).WithErrorMessage(expectedError);
}
[Fact]
public void Validate_Not_Agree_To_Terms_Should_Validation_Fail()
{
var request = new UserRegistrationRequest { AgreeToTerms = false };
var result = _validator.TestValidate(request);
result.ShouldHaveValidationErrorFor(x => x.AgreeToTerms)
.WithErrorMessage("Must agree to terms of use");
}
public static class TestDataBuilder
{
public static UserRegistrationRequest CreateValidRequest()
{
return new UserRegistrationRequest
{
Username = "testuser123",
Email = "test@example.com",
Password = "<DB_PASSWORD_PLACEHOLDER>",
ConfirmPassword = "<DB_PASSWORD_PLACEHOLDER>",
BirthDate = new DateTime(1990, 1, 1),
Age = 34,
PhoneNumber = "0912345678",
Roles = new List<string> { "User" },
AgreeToTerms = true
};
}
public static UserRegistrationRequest WithUsername(this UserRegistrationRequest request, string username)
{
request.Username = username;
return request;
}
public static UserRegistrationRequest WithEmail(this UserRegistrationRequest request, string email)
{
request.Email = email;
return request;
}
}
// Usage example
var request = TestDataBuilder.CreateValidRequest()
.WithUsername("newuser")
.WithEmail("new@example.com");
This skill can be combined with:
A: Use Mock to isolate database dependencies:
_mockUserService.IsUsernameAvailableAsync("username")
.Returns(Task.FromResult(false));
A: Use FakeTimeProvider to control time:
_fakeTimeProvider.SetUtcNow(new DateTime(2024, 1, 1));
A: Test each condition separately, ensuring complete coverage:
// Test birthday passed scenario
// Test birthday not yet arrived scenario
// Test boundary date
A: Focus on testing:
This skill provides the following template files:
templates/validator-test-template.cs: Complete validator test exampletemplates/async-validator-examples.cs: Async validation examplesThis skill content is distilled from the "Old School Software Engineer's Testing Practice - 30 Day Challenge" article series:
unit-test-fundamentals - Unit testing basicsnsubstitute-mocking - Test doubles and mocking还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Patterns and techniques for evaluating and improving AI agent outputs.
中文简介正在准备中。当前显示原文说明。
Comprehensive AI prompt engineering safety review and improvement prompt. Analyzes prompts for safety, bias, security vulnerabilities, and effectiveness while providing detailed improvement recommendations.
中文简介正在准备中。当前显示原文说明。
Use when user requests research requiring multiple sources, comprehensive analysis, or synthesis across topics - technical research, domain knowledge gathering, market analysis, or learning about complex subjects
中文简介正在准备中。当前显示原文说明。
AI-powered wiki generation for code repositories with commands, agents, and skills
中文简介正在准备中。当前显示原文说明。
Use when building .NET 10 or C# 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern, Channels, or validation; when seeing outdated patterns like old extension method syntax
中文简介正在准备中。当前显示原文说明。
Implements accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing per platform.
中文简介正在准备中。当前显示原文说明。