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

"try/catch statement" check prevents Xtend-generated code from working #241

Closed
borisbrodski opened this Issue Nov 20, 2015 · 3 comments

Comments

3 participants
@borisbrodski

borisbrodski commented Nov 20, 2015

I'm the maintainer of the JMockit-Xtend project: https://github.com/borisbrodski/jmockit-xtend

With this project you can use JMockit directly from Xtend using much nicer syntax, like:

mock [
    service.processInt(with [ it > 0 ])
    result = 2
]

(Match the call to the service.processInt(int a) with any a > 0 and return 2)

During migration to the JMockit 1.20 (or 1.14) I hit the exception:

Invalid try/catch statement inside expectation block

This happens because of the fact, that Xtend generates mandatory try/catch block for each lambda expression. Lambdas are particularly useful to match arguments or to return custom results:

stub [
    service.generateEMail(any, any, any)
    result = [ String to, String subject, String body |
        '''
            To: «to»
            Subject: «subject»
            «body»
        '''.toString
    ]
]

Analyzing the code of JMockit I found no way to disable "try/catch statement" checking.

Could you please add a "disable try/catch statement" option to the next release?
Please keep in mind, that I don't have any control over "-D" java parameters.
A global static boolean field or local switch disabling the check just for the upcoming expectations-block will both do the trick.

Here are some additional snippets for you:

Xtend:

stub [
  expectationsAPI.paramsString(with [ (it ?: "").length > 3 ])
  result = "match1"
]

generates

final JMockitExtension.XtendNonStrictExpectations _function = new JMockitExtension.XtendNonStrictExpectations() {
  @Override
  public void apply(final ExpectationsDelegate it) {
    try {
      final Function1<String, Boolean> _function = new Function1<String, Boolean>() {
        public Boolean apply(final String it) {
          String _elvis = null;
          if (it != null) {
            _elvis = it;
          } else {
            _elvis = "";
          }
          int _length = _elvis.length();
          return Boolean.valueOf((_length > 3));
        }
      };
      String _with = it.<String>with(_function);
      WithMethodsWorkAsExpectedSpec.this.expectationsAPI.paramsString(_with);
      it.setResult("match1");
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
};
JMockitExtension.stub(_function);
@rliesenfeld

This comment has been minimized.

Show comment
Hide comment
@rliesenfeld

rliesenfeld Nov 20, 2015

Member

I think there's a better solution, which is to allow conditions/try..catchs inside methods, while still disallowing them inside constructors of the Expectations/Verifications subclass. I can make this change for the next release.

Member

rliesenfeld commented Nov 20, 2015

I think there's a better solution, which is to allow conditions/try..catchs inside methods, while still disallowing them inside constructors of the Expectations/Verifications subclass. I can make this change for the next release.

@rliesenfeld rliesenfeld self-assigned this Nov 20, 2015

@borisbrodski

This comment has been minimized.

Show comment
Hide comment
@borisbrodski

borisbrodski Nov 20, 2015

Cool! Thank you!

PS
Are you aware of the fact, that I subclass XxxxxxExpectation and use JMockitExtension.XtendXxxxxxExpectations in the Xtend?

borisbrodski commented Nov 20, 2015

Cool! Thank you!

PS
Are you aware of the fact, that I subclass XxxxxxExpectation and use JMockitExtension.XtendXxxxxxExpectations in the Xtend?

@sswilliam

This comment has been minimized.

Show comment
Hide comment
@sswilliam

sswilliam Dec 16, 2015

Hi, I just started to use JMockIt in my unit testing and I feel this mock framework is really awesome. I also meet this questions when writing code for Verfications. I am just curious about why conditional checking is enabled in such blocks? Because from my point of view, it quite makes sense to support try/catch in such blocks. I suspect that I am not doing as the best practice if it is not supported.

Here is my code

//verify
        new Verifications(){
            {

                Object data;
                channel.writeAndFlush(data = withCapture());times = 1;
                assertTrue(data instanceof ByteBuf);

                try {
                    CodeProtobufPackPair pair = CodeProtobufPackUtils.unpack((ByteBuf)data);
                    assertEquals(MainServerProtocal.LOGIN, pair.code);
                    LoginResponse resp = LoginResponse.parseFrom(pair.data);
                    assertEquals(MainServerProtocal.COMMON_STATUS_PASS, resp.getStatus());
                } catch (Exception e) {
                    fail("test failed due to "+e.getMessage());
                    // TODO: handle exception
                }




            }
        };

I am doing some verifications to check whether returned protobuf data is correct or not. So I mocked the Channel object in Netty and captured the returned protobuf data. However the Protobuf will throws some exceptions and I have to use the try catch to avoid errors.

sswilliam commented Dec 16, 2015

Hi, I just started to use JMockIt in my unit testing and I feel this mock framework is really awesome. I also meet this questions when writing code for Verfications. I am just curious about why conditional checking is enabled in such blocks? Because from my point of view, it quite makes sense to support try/catch in such blocks. I suspect that I am not doing as the best practice if it is not supported.

Here is my code

//verify
        new Verifications(){
            {

                Object data;
                channel.writeAndFlush(data = withCapture());times = 1;
                assertTrue(data instanceof ByteBuf);

                try {
                    CodeProtobufPackPair pair = CodeProtobufPackUtils.unpack((ByteBuf)data);
                    assertEquals(MainServerProtocal.LOGIN, pair.code);
                    LoginResponse resp = LoginResponse.parseFrom(pair.data);
                    assertEquals(MainServerProtocal.COMMON_STATUS_PASS, resp.getStatus());
                } catch (Exception e) {
                    fail("test failed due to "+e.getMessage());
                    // TODO: handle exception
                }




            }
        };

I am doing some verifications to check whether returned protobuf data is correct or not. So I mocked the Channel object in Netty and captured the returned protobuf data. However the Protobuf will throws some exceptions and I have to use the try catch to avoid errors.

@jmockit jmockit locked and limited conversation to collaborators Dec 16, 2015

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.