[英]Unit testing generic extension method with nUnit
我向XElement
類編寫了擴展方法,此后我想對其進行測試,但是在單元測試中調用它時遇到了困難。 我也想使測試通用。
這是方法, AsBoolean
是字符串的簡單擴展,並不重要:
/// <summary>
/// Safely gets value from attribute.
/// </summary>
/// <typeparam name="T"> Return type.</typeparam>
/// <param name="xElem"><see cref="XElement"/> in which attribute will be searched.</param>
/// <param name="attrName"> Name of the attribute that is going to be searched. </param>
/// <param name="defaultValue"> Default value of the return value. </param>
/// <param name="throwExceptions"> Determines if this method will throw exceptions. </param>
/// <returns> Converted value to type <see cref="T"/></returns>
public static T SafeGetValue<T>(this XElement xElem, string attrName, T defaultValue = default(T), bool throwExceptions = false)
{
// Sets up default value for result
var result = defaultValue;
var value = xElem.Attribute(attrName)?.Value;
if (value == null) { return result; }
try
{
// Treats boolean type a bit differently as .NET converter is a bit harsh.
if (typeof(T) == typeof(bool))
{
// Converts string to boolean using custom extension
result = (T) Convert.ChangeType(value.ToBoolean(), typeof(T));
return result;
}
result = (T) Convert.ChangeType(value, typeof(T));
return result;
}
catch (InvalidCastException ex)
{
Logger.LogManager.GetLogger($"{nameof(XElementExtensions)} " +
$"threw {ex} because it can't convert {value} to type {typeof(T)}");
if (throwExceptions)
{
throw;
}
}
catch (Exception ex)
{
Logger.LogManager.GetLogger($"{nameof(XElementExtensions)} threw {ex}!");
if (throwExceptions)
{
throw;
}
}
return result;
}
現在我要像這樣測試它:
[TestFixture]
public class SafeGetValueTests
{
private XDocument _doc;
[SetUp]
public void Setup()
{
_doc = XDocument.Parse(@"
<root>
<bool></bool>
<int></int>
<string></string>
<double></double>
<decimal></decimal>
<datetime></datetime>
</root>
");
}
[TestCase("bool","boolAttr", 234235, typeof(bool))]
[TestCase("bool", "boolAttr", "dsfgdf", typeof(bool))]
[TestCase("bool", "boolAttr", 234235, typeof(bool))]
public void SafeGetValueShouldReturnDefaultValueWhenInvokedWithTypeThatCannotBeConvertedToTheValue(
string elementName, string attrName, object attrValue, Type type)
{
//Arrange
_doc.Element(elementName)?.SetAttributeValue(attrName, attrValue);
var genericMethod = typeof(XElementExtensions).GetMethod("SafeGetValue");
genericMethod = genericMethod.MakeGenericMethod(type);
//Act
var value = genericMethod.Invoke(_doc.Element(elementName),
BindingFlags.OptionalParamBinding |
BindingFlags.InvokeMethod |
BindingFlags.Static,
null,
new[] {attrName , Type.Missing, Type.Missing},
CultureInfo.InvariantCulture);
//Assert
Assert.AreEqual(value, default(bool));
}
}
但是,調用始終失敗:
mscorlib.dll中發生類型'System.Reflection.TargetParameterCountException'的異常,但未在用戶代碼中處理。其他信息:參數計數不匹配。
如何測試這種情況?
SafeGetValue
接受4個參數,在調用中您傳遞了3:
new[] {attrName , Type.Missing, Type.Missing},
您缺少第一個參數XElement
可能你想通過
new[] {_doc.Element(elementName), attrName , Type.Missing, Type.Missing},
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.