The reason you're getting this result is that you are boxing the integers to object type, and object types use the object reference to determine equality (and this would not happen for boxed objects) using the == operator.
One way to resolve this issue would be to make your method generic (which takes in any type), and then use the Equals method of the type itself (which for integers would be a comparison of the values). By making the method generic, you also remove the unnecessary boxing operation:
public static string Assert<T>(bool equals, T obj1, T obj2)
{
    bool areEqual = obj1.Equals(obj2);
    if (equals == areEqual)
    {
        return "\n\nSuccess!\n\n";
    }
    return "\n\nFailure!\n\n";
}
Now, there still may be some issues if T is a nullable type and obj1 is null, because we'll get a NullReferenceException if we try to call Equals on a null object.
To get around this, we might do a couple of things:
- Check for ReferenceEqualsfirst, which will returntrueif both arguments arenull. This will also short-circuit the need to callEqualsif two references to the same object are passed in.
- Check if obj1is notnullbefore calling itsEqualsmethod
For example:
public static string Assert<T>(bool equals, T obj1, T obj2)
{
    bool areEqual = false;
    if (ReferenceEquals(obj1, obj2))
    {
        areEqual = true;
    }
    else if (obj1 != null)
    {
        areEqual = obj1.Equals(obj2);
    }
    if (equals == areEqual)
    {
        return "\n\nSuccess!\n\n";
    }
    return "\n\nFailure!\n\n";
}
Now if we want to, we can shorten the code using conditional || and && operators and the ?: ternary operator:
public static string Assert<T>(bool equals, T obj1, T obj2)
{
    bool areEqual = ReferenceEquals(obj1, obj2) || obj1 != null && obj1.Equals(obj2);
    return equals == areEqual
        ? "\n\nSuccess!\n\n"
        : "\n\nFailure!\n\n";
}