Since years I’m using Metadata and Tooling Apex classes to connect with those APIs (based on Andrew Fawcetts work here https://github.com/afawcett/apex-toolingapi). Today I’m encountering a very strange issue in form of an package upload error which I can not understand. The issue seems totally wired and without any logical connection…
In hours of work, I was finally able to drill it down to just 3 easy things, 100% reproducible within minutes:
- ToolingAPI.cls (http://www.elastify.org/ToolingAPI.cls) – set to API v36.0
- ToolingAPITest.cls (http://www.elastify.org/ToolingAPITest.cls) – v36.0, too.
- One empty Lightning Component (details below)
Due to size limits I could not save the post with all the code, so I put the classes on my homepage. These are older versions from around 2013, but still work flawlessly.
With just the two classes:
- you can run tests: they succeed with no problems.
- create a new unmanaged package
- add both classes to the package
- upload the package: no problems, tests succeed again.
Now let’s add a blank component:
- create an new empty lightning component (only
<aura:component ></aura:component>
) with developer console.- add that to the package
- and upload it: all good, it still works, no problem!
Finally we add a controller:
- create an empty(!) JS controller inside the lightning component (consisting just of
({})
).- try to upload the package again ==> now the Apex tests are failing with
System.CalloutException: You have uncommitted work pending. Please
commit or rollback before calling outClass.ToolingAPI.submitRestCall: line 2355, column 1,
Class.ToolingAPI.submitRestCall: line 2317, column 1,
Class.ToolingAPI.submitRestCall: line 2309, column 1,
Class.ToolingAPI.query: line 132, column 1,
Class.ToolingAPITest.testQueryApexClassMember: line 67, column 1
- running the test with Dev Console or at setup: no error!
- deleting just the empty controller, I can upload the package again, the error disappeared!
- API version of the compo seems irrelevant. I’ve tried v36.0 and v41.0, no differece.
I can’t figure what can be wrong here. At this point, I can only think of a very strange salesforce error.
It must be related to callouts in conjunction with the existence of a lightning componets JS controller. Crazy! I have another class wrapping the metadata-api based on https://github.com/financialforcedev/apex-mdapi: with that the same is happening.
Update 2017-10-16 – existing package-members immune
I have older packages which contains lots of lightning compos with controllers already. Those I still can upload together with ToolingAPI with no issues – only new compos added are creating the error. However if you save the existing component they will start to produce that error, too. Luckily I got one disposable component to try this… So now I can’t make any changes to all of my vital lightning components, or I will loose the ability to upload the package. Not nice!
Update (2017-10-18) – possibly related with test.setMock()
I think that it is related to the mockup tests. It looks like the
Test.setMock()
is not working (e.g. line 56 ofToolingAPITest.cls
) and during the tests, not the mockup, but the real callout is invoked. And as a result it’s failing.As a workaround I’m trying to hack some
test.isRunningTest()
into the code and trying to return null instead something “meaningful”. Also I have to wipe allSystem.assert...()
to make this fly. But this hack is total crap, plus messing up the code, plus it will degrade my coverage. Bottom-line: this workaround is not OK, but I have to upload this package with a lot of time-pressure – no matter what.For a real solution I’m out of ideas. Totally.
Unfortunately I have no premier support and Salesforce will shut my ticket down in the support immediately.
Answer
I was able to replicate this issue in two packages, so have raised it with support, and they are currently researching it (they were able to re-create it)
One thing I noticed as a workaround – I had many classes with mock callouts, both Web Service and HTTP. But only some failed – and they both did NOT make use of Start/Stop Test.
So even though they worked fine in regular test runs, once I updated my tests to invoke the code that invokes the callouts like below, I could then upload the package.
Test.StartTest()
//Invoke code that makes callout
Test.Stop Test()
Attribution
Source : Link , Question Author : Uwe Heim , Answer Author : BritishBoyinDC