NullReferenceException
krilbe opened this issue · 1 comments
I have a static class with a single static method, but whenever I try to Setup a mock call to it, I get a NullReferenceException. If I write another method with the same signature, but dummy code, and Setup that one instead, it works. So there must be something within my method that Smocks can't handle correctly.
Here's the complete method:
public static object HämtaParametrar(string[] args, Type parameterklass)
{
Regex växelmönster = new Regex(@"^[-/](\w+)");
HashSet<string> ejHittadeObligatoriskaVäxlar = new HashSet<string>(
parameterklass.GetProperties()
.Select(pi => pi.GetCustomAttribute<KörningsparameterAttribute>())
.Where(attr => attr != null && attr.Obligatorisk)
.Select(attr => attr.Växel)
);
object parametrar = Activator.CreateInstance(parameterklass);
int argnum = 0;
while (++argnum < args.Length)
{
string arg = args[argnum];
Match träff = växelmönster.Match(arg);
if (!träff.Success)
LoggaOchKastaUndantag($"Parametern \"{arg}\" ser inte ut som en växel; ska inledas med - eller /.");
string växelnamn = träff.Captures[0].Value.Substring(1);
var propOchAttr = parameterklass.GetProperties()
.Select(pi => new { Prop = pi, Attr = pi.GetCustomAttribute<KörningsparameterAttribute>() })
.Where(pa => pa.Attr != null && pa.Attr.Växel == växelnamn)
.FirstOrDefault();
if (propOchAttr == null)
LoggaOchKastaUndantag($"Växeln \"{växelnamn}\" verkar inte existera för angiven körning.");
PropertyInfo propinfo = propOchAttr.Prop;
KörningsparameterAttribute attr = propOchAttr.Attr;
switch (attr.Parametertyp)
{
case KörningsparameterTyp.Flagga:
if (propinfo.PropertyType != typeof(bool))
LoggaOchKastaUndantag($"Växeln \"{växelnamn}\" är markerad som {attr.Parametertyp} med är inte av typen bool.");
propinfo.SetValue(parametrar, true);
break;
case KörningsparameterTyp.Text:
if (propinfo.PropertyType != typeof(string))
LoggaOchKastaUndantag($"Växeln \"{växelnamn}\" är markerad som {attr.Parametertyp} med är inte av typen string.");
++argnum;
if (argnum >= args.Length)
LoggaOchKastaUndantag($"Växeln \"{växelnamn}\" ska följas av ett textvärde, men står sist bland parametrarna.");
propinfo.SetValue(parametrar, args[argnum]);
break;
default:
LoggaOchKastaUndantag($"Hittade okänd parametertyp \"{attr.Parametertyp}\" för växeln \"{växelnamn}\"");
break;
}
ejHittadeObligatoriskaVäxlar.Remove(växelnamn);
}
if (ejHittadeObligatoriskaVäxlar.Count > 0)
LoggaOchKastaUndantag($"Följande obligatoriska växlar saknas: {string.Join(", ", ejHittadeObligatoriskaVäxlar.Select(s => $"\"{s}\""))}");
return parametrar;
}
The method LoggaOchKastaUndantag
just logs the message (log4net) and then throws an exception with the same message:
private static void LoggaOchKastaUndantag(string meddelande)
{
log.Fatal(meddelande);
throw new ArgumentException(meddelande);
}
Sorry about the Swedish identifiers... What might be "wrong" with the method? It does seem to work as intended outside of Smocks.
Here's the dummy method that works:
public static object Test(string[] a, Type t)
{
if (t.Name.StartsWith("I"))
return a;
else
return a.Length;
}
Here's the unit test method I'm trying with:
[TestMethod]
public void HittarKörningsklassen()
{
Smock.Run(context =>
{
string[] args = new string[] { };
Type paramklass = typeof(TestkörningParams);
context.Setup(() => Körningsparameterhämtare.HämtaParametrar(args, paramklass)).Returns(6);
context.Setup(() => Körningsparameterhämtare.Test(args, paramklass)).Returns(6);
}
If I have the first Setup
line there, I get a NullReferenceException
on the Smock.Run
line. If I comment it out, everything runs just fine.