Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullReferenceException #35

Open
krilbe opened this issue Sep 19, 2017 · 1 comment
Open

NullReferenceException #35

krilbe opened this issue Sep 19, 2017 · 1 comment

Comments

@krilbe
Copy link

krilbe commented Sep 19, 2017

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.

@krilbe
Copy link
Author

krilbe commented Sep 19, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant