2016-04-12 7 views
2

REF: A .NET Fiddle (в основном) приведенный ниже код.Не знаете, как протестировать эту строку .NET с FluentValidation

Я пытаюсь проверить, если string является действительным Uri использованием 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); 
    } 
} 

и для теста проверки ...

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); 
    } 
} 

но последняя строка в этом методе испытаний не компилируется:

enter image description here

Может ли кто-нибудь помочь, пожалуйста? Как я могу дать подсказку компилятору, чтобы сообщить, какой метод использовать.

+1

Нет никакого способа, потому что ваши типы - это одна и та же строка, строка. Вам придется использовать другую технику, чтобы ваша лямбда не была l => l. У меня мало опыта в этом, но я никогда не видел, чтобы кто-то использовал это без проверки свойства. l => l.blah – Mikanikal

ответ

2

Таким образом, это невозможно, так как оно находится внутри библиотеки, которую вы не можете изменить. См. here.

Однако есть работа. И это нужно, чтобы общие аргументы были не то же самое.

Вот рабочий код:

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) 
    } 
} 

Я не слишком хорошо знакомы с тем, как библиотека работает FluentValidation - так что может быть опрятнее способ обернуть это взломать

Также обратите внимание, что я изменил путь вы обнаруживаете Uri строки. TryCreate вернет true для любой строки (я не смог найти случай, когда он был когда-либо ложным).

+0

re: 'TryCreate' и true vs false. Измените его на 'UriKind.Absolute'. –

+1

также @rob .. проверьте этот хороший способ проверить, является ли строка-uri законной: http://stackoverflow.com/a/25654227/30674 –

+1

@ Pure.Krome Nice find :) Я отредактировал его в ответ с атрибуцией – Rob