使用 IoC 的 MVC 2 验证属性单元测试

发布于 2024-09-16 11:47:15 字数 1843 浏览 6 评论 0原文

我目前正在为 ASP.NET MVC 2 控制器编写一些单元测试,并且在 MVC 2.0 验证属性方面遇到一些问题。有问题的验证属性使用存储库来检查当前数据源中是否不存在重复名称,并且我想在单元测试期间用假存储库替换该存储库。我正在使用温莎城堡,按照 这篇文章,它允许我在运行时替换存储库,但不确定如何在单元测试期间执行此操作。

大部分测试代码如下:

[TestMethod]
    public void TestSaveDuplicateTitleNameReturnsValidationErrorView()
    {
        //Arrange
        var titleRepository = new FakeTitleRepository();
        var controller = new TitleController(titleRepository);            

        var selectedTitle = new Title();
        selectedTitle.Name = "Fru";

        //Act
        var actual = controller.Save(selectedTitle);

来自控制器的代码示例如下:

 public ActionResult Save(Title SelectedTitle)
    {
        if (TryValidateModel(SelectedTitle))
        {
            TitleRepository.Add(SelectedTitle);
            TitleRepository.Save();

测试期间在控制器本身中使用的存储库是我已经通过的假存储库,但是当 TryValidateModel 触发并运行以下代码时它会导致异常,因为存储库为空:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class ValidTitleNameAttribute : ValidationAttribute
{
    public ITitleRepository Repository { get; set; }

    public override bool IsValid(object value)
    {
        bool isValid = true;

        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
        object name = properties.Find("Name", true).GetValue(value);

        if (name == null)
        {
            return isValid = false;
        }

        var titles = Repository.GetAllTitles();

显然,在存储库属性中,我可以设置一个默认实例来引用具体存储库,这将防止测试期间出现异常,但这会破坏使用 IoC 容器的目的。解决这个问题的最佳方法是什么,是找到一种以某种方式模拟验证属性的方法,还是有一种方法 Windsor 可以在单元测试运行时注入假存储库?任何帮助/建议将不胜感激。

I am currently writing some unit tests for an ASP.NET MVC 2 controller and having some issues with the MVC 2.0 validation attributes. The validation attribute in question uses a repository to check that no duplicate names exist in the current data source, and I would like to replace this repository with a fake one during my unit test. I am using Castle Windsor, as per this article, which allows me to replace the repository at run time, but am not sure how I can do this during the unit test.

The bulk of the test code is this:

[TestMethod]
    public void TestSaveDuplicateTitleNameReturnsValidationErrorView()
    {
        //Arrange
        var titleRepository = new FakeTitleRepository();
        var controller = new TitleController(titleRepository);            

        var selectedTitle = new Title();
        selectedTitle.Name = "Fru";

        //Act
        var actual = controller.Save(selectedTitle);

A code sample from the controller is below:

 public ActionResult Save(Title SelectedTitle)
    {
        if (TryValidateModel(SelectedTitle))
        {
            TitleRepository.Add(SelectedTitle);
            TitleRepository.Save();

The repository being used in the controller itself during the test is my fake one that I have passed, but when the TryValidateModel fires and the following code is run then it causes an exception as the repository is null:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class ValidTitleNameAttribute : ValidationAttribute
{
    public ITitleRepository Repository { get; set; }

    public override bool IsValid(object value)
    {
        bool isValid = true;

        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
        object name = properties.Find("Name", true).GetValue(value);

        if (name == null)
        {
            return isValid = false;
        }

        var titles = Repository.GetAllTitles();

Obviously in the repository property I could set a default instance to reference a concrete repository, which would prevent the exception during testing but that would defeat the purpose of using the IoC container. What would be the best way round this issue, would it be to find a way to mock the validation attribute in some way, or is there a way Windsor can inject the fake repository when the unit test runs? Any help/advice would be much appreciated.

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

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

发布评论

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

评论(1

夜清冷一曲。 2024-09-23 11:47:15

我认为最好的办法是为您的单元测试创​​建一个假的 DataAnnotationsModelValidator,它将在测试期间注入您的假存储库。您应该能够使其变得相当简单,以限制它导致单元测试出现任何问题的可能性。

I think the best thing to do would be to create a fake DataAnnotationsModelValidator for your unit test that will inject your fake repository during testing. You should be able to make it fairly simple so as to limit the chances of it causing any issues with your unit tests.

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