单元测试时,应在ExpectedExceptionAttribute中使用哪种类型的异常

本文关键字:种类 类型 异常 应在 ExpectedExceptionAttribute 单元测试 | 更新日期: 2023-09-27 18:28:02

我正在进行单元测试。我想使用ExpectedExceptionAttribute。

我有一个包含username属性的employee类,我在该类上使用了索引,所以username应该是唯一的。

代码如下。

  public class EmployeeConfigration : EntityTypeConfiguration<Employee>
        {
            public EmployeeConfigration()
            {
                this.Property(x => x.FirstName).IsRequired().HasMaxLength(50);
                this.Property(t => t.UserName).HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_UserName", 1) { IsUnique = true }));
            }
        }

现在,考虑下面的单元测试代码。

 [TestMethod]
        [ExpectedException(typeof(System.Data.SqlClient.SqlException), "Username duplication is not allowded")]
        public void Insert_EmployeeWithSameUsername_Fails()
        {
          ...
          ...
          ...
          }

我使用过SqlException,但它不起作用,它仍然会抛出一个错误。。。在单元测试代码中应该使用哪种异常?

单元测试时,应在ExpectedExceptionAttribute中使用哪种类型的异常

来自MSDN:

如果抛出的异常继承自预期的异常,则测试将失败。

看起来您实际上得到了一个从SqlException派生的异常。

使用这个而不是属性,或者如果可以的话,使用xUnit/NUnit更好。

try
{
    //code
}
catch (SqlException se)
{
}
catch (Exception e)
{
    Assert.Fail(
         string.Format( "Unexpected exception of type {0} caught: {1}",
                        e.GetType(), e.Message )
    );
}

使用EF 6或更高版本时,违反唯一索引约束将引发DBUpdateException。我不确定EF的其他版本。唯一的问题是,每当数据库出现其他问题时,就会抛出DBUpdateException,因此没有明确的方法来测试违反唯一索引的情况。考虑这个代码:

        try
        {
           //some code here that causes the error
        }
        catch (DbUpdateException ex)
        {
            var updateException = ex.InnerException as UpdateException;
            if (updateException != null)
            {
                var sqlException = updateException.InnerException as SqlException;
                // UIX or PK violation, so try to update/insert.
                var uixViolationCode = 2601;
                var pkViolationCode = 2627;
                if (sqlException != null && sqlException.Errors.OfType<SqlError>().Any(se => se.Number == uixViolationCode || se.Number == pkViolationCode))
                {
                    // handle the required violation
                }
                else
                {
                    // it's something else...
                    throw;
                }
            }
            else
            {
                throw;
            }
        }