1

我们基于列的数据库的数据字段映射到 DataField 类。在每个数据字段对象上GetValue<T>()都可以调用该方法。

如果T是非法类型,则会引发异常。我应该在我的单元测试中通过什么类型,如果我通过非法类型,我会测试是否抛出异常?我想到的下一个已知的非法类型?还是有更抽象的方法?

public object GetValue<T>()
{
    if (typeof(T) == typeof(string)) return ValueString;
    if (typeof(T) == typeof(int?)) return ValueInt;
    if (typeof(T) == typeof(double?)) return ValueDouble;
    if (typeof(T) == typeof(DateTime?)) return ValueDateTime;
    if (typeof(T) == typeof(bool)) return ValueBoolean == true;

    var ex = new Exception("Following type is not supported: " + typeof(T));
    Log.Error(ex);
    throw ex;
}

因此,除了那些之外的所有类型,如果它们被通过,都应该抛出这个异常。所以我需要一种虚拟类型,对吧?

目前我的单元测试如下所示:

[Fact]
public void If_T_is_illegal_type_an_exception_gets_thrown()
{
    _dataField = new DataField(_params);
    Assert.Throws<Exception>(() => _dataField.GetValue<Type>());
}
4

3 回答 3

2

请记住,单元测试试图通过所有代码路径并确保正确的行为。您总共应该有 6 个测试:一个针对 5 种有效类型中的每一个,一个针对任何其他类型(如您当前所拥有的)以涵盖最终的代码路径。不知道为什么你需要更抽象的东西。

您可能更喜欢使用显式转换和强制转换,以便这成为编译时测试而不是运行时:http: //msdn.microsoft.com/en-us/library/xhbhezf4 (v=vs.100).aspx

于 2012-04-25T09:44:41.240 回答
0

如上所述,对每种支持的类型进行一次测试,对不支持的类型进行一次测试就足够了。

我确实注意到的一件事是异常不是错误的唯一预期结果。您如何验证错误是否已记录?
你有办法做到这一点吗?
如果没有,你想要/需要一个吗?

此外,一个完全不请自来的代码审查点......为什么

if (typeof(T) == typeof(bool)) return ValueBoolean == true; 

代替

if (typeof(T) == typeof(bool)) return ValueBoolean; 

艾伦。

于 2012-04-25T10:07:01.090 回答
0

目前,如果您调用GetValue<bool>()您的代码将调用typeof(T)五次并进行 5 次比较。然后它将返回装箱的布尔值作为对象。最糟糕的是,这个方法的签名没有说明哪些类型是允许的,哪些会抛出异常。我可以打电话GetValue<decimal>()吗?不知道。如果不允许,我应该尝试运行时异常。

考虑为所需类型创建重载方法:

bool GetBooleanValue()
decimal GetDecimalValue()

这完美地描述了它可以返回的类型。里面没有长链。调用者不会收到对象。您将毫无疑问地对每种方法进行测试。

于 2012-04-25T10:04:41.963 回答