2

I am in the midst of writing a Test class for my code and there is a snippet of code that passes that I know should be failing.

The code below will always pass:

TestUtilities.SoftAssertEquals(IfCausedException instanceof SOQLUnitOfWork.SOQLUnitOfWorkException, true);

Even though IfCauseException is null - I printed it out with a simple debug statement to verify this). Also, I printed out the check to see what it is returning (the instanceof) and that returns true when it shouldn't.

So the question is, why is this returning true when it shouldn't.

I appreciate anyone's help in advance.

Edit:

I also tested this by simply printing the value back - i.e.

System.Debug(LoggingLevel.Info, IfCauseException instanceof SOQLUnitOfWork.SOQLUnitOfWorkException)

It still returns true.
For a clearer example:
Exception IfCausedException = null;
        System.Debug(LoggingLevel.Info,'\n\n This is it ' + 
            (IfCausedException instanceof SOQLUnitOfWork.SOQLUnitOfWorkException) + '\n\n');

returns 'This is it true'.

This is my solution (big thanks to Peter on this!)
All I needed was to add the following:


if(!TestUtilities.IsDisabled('Assert should fail'))
   TestUtilities.SoftAssertEquals(IfCausedException instanceof 
   SOQLUnitOfWork.SOQLUnitOfWorkException
   && IfCausedException != null, true);

This roughly translates to this:


System.Assert((SOQLUnitOfWork.SOQLUnitOfWorkException
   && IfCausedException != null) == true)

For rao
This is the method you wanted. I didn't post it because all I was worried about was the true/false return on the instanceof keyword. But, here is the method anyway.

return (!isSoftAssert()) ? System.assert(ObjectOne == ObjectTwo) != null:
   (ObjectOne == ObjectTwo) ? 
   System.debug(LoggingLevel.Info, '\n\nSoft Assert Succeeded: [' + ObjectOne + ' = ' + ObjectTwo + ']\n')  == null:
   System.debug(LoggingLevel.Info, '\n\nSoft Assert Failed: [' + ObjectOne + ' != ' + ObjectTwo + ']\n') != null;
Note: This is an altered implementation by Adam (the user here on SE)

7
  • 1
    This returns a different value outside of your test classes? This may be difficult to troubleshoot since it appears to be pretty specific the things you have written. Jul 15, 2013 at 20:23
  • 1
    go to setup-->develop --> apexclasses search for TestUtilities and look for softAssertEquals and post the complete method in your question to debug further
    – Rao
    Jul 15, 2013 at 20:25
  • Hold on, let me test that theory. Apparently, this is happening regards of if it is in a Test class - oiy. Jul 15, 2013 at 20:26
  • @rao : I went ahead and tested the instanceof keyword outside the method to see if it is returning the wrong result - which it did. I reflected that in my edit of the original post. Jul 15, 2013 at 20:34
  • Where is the method we need to say what it takes in as params and what it returns to tell what might be happening, added it the system.debug gives a true then the assertion seems to be working fine, what is the issue now :/
    – Rao
    Jul 15, 2013 at 20:39

1 Answer 1

7

As far as I know, instanceof in Apex has always returned true when the operand is null, which is not consistent with Java which will return false.

The instanceof documentation doesn't explictly address the situation where the operand is null.

For what it's worth, I found this blog post which observed it in 2010.


According to the Winter 15 Release Notes this is scheduled to change. Note that this isn't the finalised release so is subject to change.

instanceof keyword:

Versioned behavior change when instanceof is used with a null object

In Apex saved with API version 32.0 and later, instanceof returns false if the left operand is a null object. For example, the following sample returns false.

Object o = null;
Boolean result = o instanceof Account;
System.assertEquals(false, result);

In API version 31.0 and earlier, instanceof returns true in this case.

8
  • 2
    object t = null; system.debug(t instanceof integer); system.debug(t instanceof date); system.debug(t instanceof datetime); system.debug(t instanceof string);
    – sfdcfox
    Jul 16, 2013 at 2:54
  • 1
    This returns "true", "true", "true", and "true." Null is an instance of everything that can be null (which is everything). Just for clarification. So, one should always check for null before instanceof.
    – sfdcfox
    Jul 16, 2013 at 2:55
  • 1
    I'd like to just a simple observation: Java's implementation is technically wrong. Instanceof basically checks to see if a variable could be cast into another variable's data type without an error. For example, you can cast a decimal into a double, and likewise you can assign a null value into a double as well.
    – sfdcfox
    Jul 16, 2013 at 3:01
  • Thank you Peter, that was quite helpful! I appreciate the clarification. I didn't know about this. And thank you for the additional comments sfdcfox! Jul 16, 2013 at 14:02
  • 1
    Not sure if this is related or not, but we did uncover a Summer '13 issue with instanceof and Id's that should be going to the known issues list -> gist.github.com/kevinohara80/5869680 Jul 16, 2013 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.