我将扩展方法写入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'类型的异常,但未在用户代码中处理。附加信息:参数计数不匹配。
如何测试这种情况?
答案 0 :(得分:1)
SafeGetValue
需要4个参数,在调用中你传递3:
new[] {attrName , Type.Missing, Type.Missing},
您缺少第一个参数XElement
可能你想传递
new[] {_doc.Element(elementName), attrName , Type.Missing, Type.Missing},