Happy Business Starts Here

Remove Zuora error on Salesforce unit tests

Remove Zuora error on Salesforce unit tests

Is there anyway to avoid the Zuora error in Salesforce unit tests that states "Please upload Zuora WSDL at first" without having to use the @isTest(SeeAllData=true) attribute? Salesforce best practices are to not use SeeAllData=true. Using SeeAllData has the potential to create other issues when testing which I'm trying to avoid.

To generate the error I simply need to attempt to create a dummy Zuora object within the context of a test

Zuora.zObject zCharge = new Zuora.zObject('RatePlanCharge');


Is there anything else I can do to prevent this error? "Please upload Zuora WSDL at first"

How does one avoid this bug if it's not really a bug but what looks like bad design?

22 Comments
Community Manager
Status changed to: More Feedback Needed
 
Guru

Is there any update on this.

 

	@isTest
	static void createZuoraObjectTest(){
		Zuora.zObject account = new Zuora.zObject('Account');
	}

This test has fatal exception:

 

09:56:10.367 (1373556593)|FATAL_ERROR|Zuora.zAPIException: Please upload Zuora WSDL at first.

Class.Zuora.zSchema.loadSchema: line 118, column 1
Class.Zuora.zSchema.isSupportedzType: line 38, column 1
Class.Zuora.zObject.<init>: line 54, column 1
Class.Z_SubscribePreviewBatch_Test.createZuoraObjectTest: line 8, column 1
09:56:10.367 (1373569184)|FATAL_ERROR|Zuora.zAPIException: Please upload Zuora WSDL at first.

Class.Zuora.zSchema.loadSchema: line 118, column 1
Class.Zuora.zSchema.isSupportedzType: line 38, column 1
Class.Zuora.zObject.<init>: line 54, column 1
Class.Z_SubscribePreviewBatch_Test.createZuoraObjectTest: line 8, column 1

This makes it very hard to have passing unit tests that use the Zuora API. Having to use SeeAllData = True is bad practice when writing unit tests.

Community Manager
Status changed to: Under Consideration
 
Scholar

Nice to see they posted my question as an idea.  Yes.. this needs to be fixed! 

Guru

So the reason that "SeeAllData=true" is needed is that the Zuora WSDL for making SOAP calls out is stored in the instance as data (not metadata), presumably in the custom settings area. This data can only be accessed if the test has access to all org data. Otherwise, the WSDL objects will be blank and the error will be thrown.

 

Now to play devils advocate here... the use of "SeeAllData=true" is only bad if your test actually depends on org level data. So you can use it in specific circumstances without doing bad things like referring to specific accounts or other data that is unlikely to exist in a clean org (or sanbox, etc). Though one could also argue that having to upload the WSDL itself to the org data constitutes a dependency on data that might not be in the environment and makes the tests less portable.

 

All that being said, it would seem a good way for Zuora to handle this is provide us with a programatic way to upload the WSDL as part of our test data... So at the start of the test i would inject the Zuora WSDL, various accounts, etc, etc, and then i could proceed with my testing. The argument could also be made for including the stock WSDL inside the package by default. However, I imagine this has some downsides since the WSDL is updated more frequently than the Salesforce managed packages and any embedded version would not have tenant specific customizations (i.e. custom fields) included in it.

Guru

I think loading the wsdl in the test might be a good way to go. That may make it possible for tests to pass on the verify step of deployment when the inbound code has dependency on a newer wsdl than what is in production. We would need a way to deploy the wsdl with the change set - possibly using static resources.

 

Using SeeAllData=true makes the test run slower.  I only use it on the isolated methods that need the wsdl.

 

 

Scholar

 Hi @feisley I appreciate your detailed response. 

 

In regards to your comment regarding "the use of "SeeAllData=true" is only bad if your test actually depends on org level data" I would present this scenario.  

 

 

 

In a fullcopy sandbox a unit test may need to create a Zuora.zObject('Account') object as well as create some custom Salesforce objects that have unique identifiers enforceable at the object level. Now in order to create these records my test custom objects can't be created with the same unique values as records that may already exist (since it's a fullcopy sandbox) so my test has to now look at existing data to make sure it's not creating test records with overlapping unique fields.  My test shouldn't have to be concerned with records that already exist but is now forced to because SeeAllData needed to be set to true. 

 

If this data is currently stored in managed Custom Settings a solution could be to migrate it to Custom Metadata types which are already visible in test methods.   This would eliminate the need to use SeeAllData=true to provide Zuora access to custom settings. 

Guru

@Jamie good point. We do have the same scenario with unique ID's that have the potential to conflict. We were lucky enough to reserve a block of them when we designed the ID format for test data to use to avoid overlap (since our other tests can span many systems, not just Salesforce).

 

Even without Zuora migrating to Custom Metadata, they should still be able to provide us an API we can call from tests to inject the WSDL with the rest of our test data so that we can perform the tests without SeeAllData=true. (Assuming there are not other dependencies to worry about)

Guru

Using Custom Metadata for all Zuora config would be my first choice.

Having an API method that loaded the wsdl would be next.

 

Anything to make testing Zuora for Salesforce code easier is a bonus, see Documenting behavior to code under test

To add to the seeAllData discussion, for orgs with large amounts of data enabling see all data leads to a significant performance degradation when running tests.

 

Additionally, using seeAllData makes the test non-deterministic and prone to erratic and hard to diagnose test failures. As an example, say we're testing code that enforces a uniqueness constraint on something. The test might assume "NotARealName" to test a uniqueness constraint. If someone happens to create a record with that name, you're test starts failing. This is a bit of a stretch and rare, but it's happened and it's a real pain to diagnose. When we know the only data in the database is stuff created by the test it's much easier to get consistent test behavior.