REF: A .NET Fiddle of (basically) the code, below.
I'm trying to test if a string
is a valid Uri
using FluentValidation:
public class LinksValidator : AbstractValidator<string>
{
public LinksValidator()
{
RuleFor(x => x)
.Must(LinkMustBeAUri)
.WithMessage("Link '{PropertyValue}' must be a valid URI. eg: http://www.SomeWebSite.com.au");
}
private static bool LinkMustBeAUri(string link)
{
if (string.IsNullOrWhiteSpace(link))
{
return false;
}
Uri result;
return Uri.TryCreate(link, UriKind.Absolute, out result);
}
}
and for the validation test...
public class LinksValidatorTests
{
private readonly LinksValidator _linksValidator;
public LinksValidatorTests()
{
_linksValidator = new LinksValidator();
}
[Theory]
[InlineData("Http://www.SomeDomain.com")]
[InlineData("https://www.SomeDomain.com")]
[InlineData("http://www.SomeDomain.com.au")]
public void GivenAValidUri_Validate_ShouldNotHaveAValidationError(string uri)
{
// Arrange.
// Act & Assert.
_linksValidator.ShouldNotHaveValidationErrorFor(l => l, uri);
}
}
but the last line in that test method doesn't compile:
How can I provide a hint to the compiler to tell it which method to use?
So, it's not possible since it's within a library you can't modify. See here.
There is a work-around, however. And that's to make sure that the generic arguments are not the same.
Here is working code:
public static void Main()
{
Console.WriteLine("Hello World");
var uri = "Http://www.SomeDomain.com";
var linksValidator = new LinksValidator();
linksValidator.ShouldNotHaveValidationErrorFor(uri);
}
public class LinksValidator : AbstractValidator<LinksValidator.UrlWrapper>
{
public class UrlWrapper { public string Url { get; set; } }
public LinksValidator()
{
RuleFor(x => x.Url)
.Must(LinkMustBeAUri)
.WithMessage("Link '{PropertyValue}' must be a valid URI. eg: http://www.SomeWebSite.com.au");
}
//Optional 'overload' since l => l.Url seems to be superfluous
public void ShouldNotHaveValidationErrorFor(string uri)
{
this.ShouldNotHaveValidationErrorFor(l => l.Url, uri);
}
private static bool LinkMustBeAUri(string link)
{
if (string.IsNullOrWhiteSpace(link))
{
return false;
}
//Courtesy of @Pure.Krome's comment and https://stackoverflow.com/a/25654227/563532
Uri outUri;
return Uri.TryCreate(link, UriKind.Absolute, out outUri)
&& (outUri.Scheme == Uri.UriSchemeHttp || outUri.Scheme == Uri.UriSchemeHttps);
}
}
I'm not too familiar with how the FluentValidation library works - so there may be a tidier way to wrap this hack
Also note, I changed the way you detect Uri
strings. TryCreate
will return true for just about any string (I was unable to find a case where it was ever false).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With