在控制器中使用ReCaptcha验证测试代码?

时间:2011-10-10 21:01:29

标签: unit-testing architecture tdd recaptcha mvcrecaptcha

这里是我的简化控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
    if (!ReCaptcha.Validate(Constants.ReCaptchaPrivateKey))
        ModelState.AddModelError("recaptcha", "Incorrect value, enter the text again.");

    if (ModelState.IsValid)
    {
        //Code for register 
    }
}

应该在哪里测试数据验证逻辑?

1 个答案:

答案 0 :(得分:0)

我会为ReCaptcha验证创建一个接口,或者代表什么,这真的是人类验证,所以像这样:

public interface IHumanValidator
{
    ///Checks validates that the currentuser is human and not a bot
    bool Validate();

    /// Returns the text to display if the validation fails
    string ValidationFailText{get;}
}

您需要更改控制器以接受构造函数中的IHumanValidator(如果必须,则更改属性)。然后将方法更改为:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
    if (!m_humanValidator.Validate())
        ModelState.AddModelError("recaptcha", m_humanValidator.ValidationFailText);

    if (ModelState.IsValid)
    {
        //Code for register 
    }
}

然后我会将一个基于ReCaptcha验证的实现注入控制器并对其进行验证:

public class ReCaptchaHumanValidator : IHumanValidator
{
    public bool Validate()
    {
        ReCaptcha.Validate(Constants.ReCaptchaPrivateKey)
    }

    public string ValidationFailText
    {
        get{return "Incorrect value, enter the text again.";}
    }
}

然后你可以注入一个模拟验证器进行测试,你可以配置它来返回有效与否,具体取决于测试。

这也有一个好处,如果您决定更改为另一种形式的验证而不是ReCaptcha,那么您只需要提供IHumanValidator的另一个实现,而不需要更改代码中的任何其他内容。