wcf 和验证应用程序块单元测试

发布于 2024-09-12 04:04:46 字数 543 浏览 8 评论 0原文

我正在尝试测试我为 wcf 服务设置的验证。最好的方法是什么?

[ServiceContract]
[ValidationBehavior]
public interface IXmlSchemaService
{

    [OperationContract(Action = "SubmitSchema")]
    [return: MessageParameter(Name = "SubmitSchemaReturn")]
    [FaultContract(typeof(ValidationFault))]
    JobData SubmitSchema([XmlStringValidator] string xmlString);
}

XmlStringValidator 是我创建的自定义验证器。理想情况下,我想要类似的东西:

XmlSchemaService service = new XmlSchemaService();
service.SubmitSchema();

但在这种情况下,不会调用验证。

I'm trying to test validation that I've setup for my wcf service. What's the best way to do it?

[ServiceContract]
[ValidationBehavior]
public interface IXmlSchemaService
{

    [OperationContract(Action = "SubmitSchema")]
    [return: MessageParameter(Name = "SubmitSchemaReturn")]
    [FaultContract(typeof(ValidationFault))]
    JobData SubmitSchema([XmlStringValidator] string xmlString);
}

XmlStringValidator is a custom validator I've created. Ideally I want something like:

XmlSchemaService service = new XmlSchemaService();
service.SubmitSchema();

But in this case, validation isn't called.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

堇色安年 2024-09-19 04:04:46

根据定义,这种测试是集成测试,而不是单元测试。仅当通过 WCF 管道调用服务操作时才会进行 VAB 验证。

虽然您也许可以在不创建客户端代理的情况下强制通过 WCF 管道进行调用,但从客户端代理测试这一点以确保客户端准确地看到您希望从服务发布的错误不是更有意义吗?当验证失败时?

By definition, this sort of test is an integration test, not a unit test. The VAB validation will only take place if the service operation is invoked via the WCF pipeline.

While you could perhaps force your calls through the WCF pipeline without creating a client proxy, wouldn't it make more sense to test this from a client proxy in order to ensure that the client is seeing exactly the fault you wish to publish from your service when the validation fails?

寒尘 2024-09-19 04:04:46

您可以单独测试验证。虽然直接运行服务代码时调用验证是不可行的,但验证应用程序块有两种测试代码的方法(据我所知)。

  1. 使用 ValidatorFactory 为您的输入类型创建验证器并断言验证结果包含预期错误。
  2. 直接实例化验证器并使用各种输入对其进行测试。

在实践中,我最终结合使用了这两种技术。我使用方法一来测试复杂输入类型的验证错误。举个例子:

[DataContract]
public class Product
{
    [DataMember, NotNullValidator]
    public string Name { get; set; }

    [DataMember, RangeValidator(0.0, RangeBoundaryType.Exclusive, 
        double.MaxValue, RangeBoundaryType.Ignore,
        ErrorMessage = "The value cannot be less than 0.")]
    public double Price { get; set; }    
}

[TestMethod]
public void InvalidProduct_ReturnsValidationErrors()
{
    Product request = new Product()
    {
        Price = -10.0
    };
    var validatorFactory = EnterpriseLibraryContainer.Current
        .GetInstance<ValidatorFactory>();
    var validator = validatorFactory.CreateValidator<Product>();
    var results = validator.Validate(request);

    Assert.IsTrue(results.Any(vr => vr.Key == "Name" 
        && vr.Message == "The value cannot be null."));
    Assert.IsTrue(results.Any(vr => vr.Key == "Price" 
        && vr.Message == "The value cannot be less than 0."));
}

对于方法 2,我将进行涵盖我创建的验证器的用例场景的测试。另一个例子:

[TestMethod]
public void XmlStringValidator_ReturnsErrors_OnInvalidInput()
{
    var validator = new XmlStringValidator();

    var results = validator.Validate("Your input goes here");

    Assert.IsTrue(results.Any(vr => vr.Key == "[KeyNameInValidator]" && 
        vr.Message == "[Expected error message based on input]"));
}

方法 2 将允许您为 XmlStringValidator 创建任意数量的测试场景。

您可以在本文中找到有关这些方法的更多信息:章节6 - 消除验证并发症

You can test out the validation in isolation. While it is not feasible to have validation invoked when running the service code directly, the Validation Application Block has two methods for testing your code (that I am aware of).

  1. Using the ValidatorFactory to create a validator for your input type and Assert that the validation results contain the expected errors.
  2. Instantiating the Validator directly and testing it with various input.

In practice I end up using a combination of the two techniques. I use method one to test for validation errors on complex input types. As an example:

[DataContract]
public class Product
{
    [DataMember, NotNullValidator]
    public string Name { get; set; }

    [DataMember, RangeValidator(0.0, RangeBoundaryType.Exclusive, 
        double.MaxValue, RangeBoundaryType.Ignore,
        ErrorMessage = "The value cannot be less than 0.")]
    public double Price { get; set; }    
}

[TestMethod]
public void InvalidProduct_ReturnsValidationErrors()
{
    Product request = new Product()
    {
        Price = -10.0
    };
    var validatorFactory = EnterpriseLibraryContainer.Current
        .GetInstance<ValidatorFactory>();
    var validator = validatorFactory.CreateValidator<Product>();
    var results = validator.Validate(request);

    Assert.IsTrue(results.Any(vr => vr.Key == "Name" 
        && vr.Message == "The value cannot be null."));
    Assert.IsTrue(results.Any(vr => vr.Key == "Price" 
        && vr.Message == "The value cannot be less than 0."));
}

For method 2 I would have tests that cover my use case scenarios for Validators I've created. As another example:

[TestMethod]
public void XmlStringValidator_ReturnsErrors_OnInvalidInput()
{
    var validator = new XmlStringValidator();

    var results = validator.Validate("Your input goes here");

    Assert.IsTrue(results.Any(vr => vr.Key == "[KeyNameInValidator]" && 
        vr.Message == "[Expected error message based on input]"));
}

Method 2 will allow you to create as many test scenarios as you would like for your XmlStringValidator.

You can find more information about these methods in this article: Chapter 6 - Banishing Validation Complication

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文