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

Implement #390 #1256

Merged
merged 4 commits into from
Aug 17, 2020
Merged

Implement #390 #1256

merged 4 commits into from
Aug 17, 2020

Conversation

WarpspeedSCP
Copy link
Contributor

@WarpspeedSCP WarpspeedSCP commented Aug 14, 2020

I've implemented #390 as a detector, DontAssertInstanceofInTests.

This only covers usages of Assert.assertTrue(obj instanceof Class) which are present in the body of an @Test annotated method.

I would like to add usages such as assertEquals(true, <instanceof expression>) but I am not completely sure of the best way to go about it.

  • Added an entry into CHANGELOG.md

Copy link
Member

@KengoTODA KengoTODA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format your code by running ./gradlew spotlessApply. I will check more with my IDE later.

spotbugs/etc/messages.xml Show resolved Hide resolved
@Override
public void visitCode(Code obj) {
if (isTest)
super.visitCode(obj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the purpose is skipping sawOpcode(int), it could be better to implement beforeOpcode(int) instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does beforeOpcode control if we want to skip processing an entire method? The intention was to avoid processing any methods that weren't annotated as tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. The javadoc describes its responsibility as return false if we should skip calling sawOpcode, and the implementation is like below:

if (beforeOpcode(opcode)) {
sawOpcode(opcode);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, beforeOpcode would run on every opcode of a method.

Now that I look, there's a shouldVisitCode method in BytecodeScanningDetector which would do exactly what I was trying to do, so I'll just override that instead of that visitCode hack.

It appears that OpcodeStackDetector.visitCode uses BytecodeScanningDetector.shouldVisitCode :

if (!shouldVisitCode(obj)) {
return;
}

so I changed my detector to be an OpcodeStackDetector instead.

@rydenius
Copy link

rydenius commented Jan 5, 2021

Following the advice of the documentation and using the instanceOf matcher, then proceeding the test by casting the object to that type in order to inspect it will then instead trigger a BC_UNCONFIRMED_CAST_OF_RETURN_VALUE error, something that does not happen after a regular instanceof call. So I need to introduce an exclude pattern for my test, or introduce a not that elegant if statement. Can you recommend a better way that was intended? I now feel that these two rules conflict a bit with each other.

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

Successfully merging this pull request may close these issues.

None yet

3 participants