【问题标题】:C# each attribute should execute the TestMethodC#每个属性都应该执行TestMethod
【发布时间】:2019-10-30 14:47:04
【问题描述】:

我创建了一个名为RoleAttribute 的自定义xUnit 理论测试DataAttribute:

public class RoleAttribute : DataAttribute
{
    public Role Role { get; set; }
    public RoleAttribute(Role role, Action<Role> method)
    {
        Role = role;
        AuthRepository.Login(role);
        method(role);
    }

    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
        return new[] { new object[] { Role } };
    }
}

而且我有测试方法OpenProfilePageTest

public class ProfileTest : AuthTest
{
    [Theory, Priority(0)]
    [Role(Enums.Role.SuperUser, OpenProfilePageTest)]
    [Role(Enums.Role.Editor, OpenProfilePageTest)]
    public void OpenProfilePageTest(Enums.Role role)
    {
        var profile = GetPage<ProfilePage>();
        profile.GoTo();
        profile.IsAt();
    }
}

我想要的是它首先执行的每个角色(属性):

AuthRepository.Login(role);RoleAttribute 的构造函数)

然后继续使用OpenProfilePageTest() 方法中的代码。在它重复相同之前,但对于第二个属性。

我怎样才能做到这一点,现在我正试图通过在属性内传递OpenProfilePageTest() 方法并在其构造函数中执行它来实现这一点。一定有比传递我相信的方法更好的方法来实现这一点吗?

【问题讨论】:

    标签: c# .net-core xunit xunit.net xunit2


    【解决方案1】:

    你可以在不通过方法的情况下实现这一点,你需要稍微修改你的属性。我更改了属性以获取您要测试的所有角色并在数据中返回它们。这是一个例子

    public class RolesAttribute : DataAttribute
    {
        private Role[] _roles;
        public RolesAttribute(params Role[] roles)
        {
            _roles = roles;
        }
    
        public override IEnumerable<object[]> GetData(MethodInfo testMethod)
        {
            var data = new List<object[]>();
            //We need to add each role param to the list of object[] params
            //This will call the method for each role
            foreach(var role in _roles)
                data.Add(new object[]{role});
            return data;
        }
    }
    

    然后在您的测试中,您只需将要测试的所有角色传递到一个属性中,就像这样

    public class ProfileTest : AuthTest
    {
        [Theory, Priority(0)]
        [Roles(Enums.Role.SuperUser, Enums.Role.Editor)]
        public void OpenProfilePageTest(Enums.Role role)
        {
            AuthRepository.Login(role);
            var profile = GetPage<ProfilePage>();
            profile.GoTo();
            profile.IsAt();
        }
    }
    

    【讨论】:

    • 是否可以通过在RoleAttribute 的构造函数中执行AuthRepository.Login(role); 方法来完成相同的操作?因为现在我需要在每个使用[Role(Enum.Role)] 的TestMethod 中添加AuthRepository.Login(role);
    • 否,因为该属性规定了对测试方法的调用。该方法获取参数。在测试本身中这样做更有意义,因为这是单个角色的上下文。
    【解决方案2】:

    Attribute 执行除提供有关其装饰成员的元数据之外的其他功能会导致不必要的复杂化而不是其设计目的。

    整个自定义属性可以取消,而使用内置数据属性

    例如

    public class ProfileTest : AuthTest {
        [Theory, Priority(0)]
        [InlineData(Enums.Role.SuperUser)]
        [InlineData(Enums.Role.Editor)]
        public void OpenProfilePageTest(Enums.Role role) {
            //Arrange
            AuthRepository.Login(role);            
            var profile = GetPage<ProfilePage>();
    
            //Act
            profile.GoTo();
    
            //Assert
            profile.IsAt();
        }
    }
    

    AuthRepository.Login 在这种情况下是执行所需用例的设置/安排的一部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 2018-06-21
      相关资源
      最近更新 更多