17

I've created a new Apex class representing a third-party SOAP web service, using the "Generate from WSDL" button. Now I'd like to deploy this class to my production environment, but I'm getting an error that my test coverage is now below 75%.

The new class is over 2500 lines, and I'd like to avoid manually writing unit tests for the entire class, partly because I'll only be using small parts of it (but want to keep the whole API available for future use), and partly because perfect functioning of this class is only a convenience, not a necessity for our business.

Is there any way to auto-generate the unit tests, or to otherwise quickly create unit tests that cover enough of my automatically generated Apex class, or possibly to just bypass the code coverage requirement for this class that doesn't need testing?

  • Auto-generating tests is probably a Bad Idea, but it'd be interesting to see if there was. – sfdcfox Dec 26 '13 at 16:02
5

Here is a blog for the solution i used for the Metadata Apex API WSDL test class. The approach uses a semi-generic WebServiceMock implementation and type instantiation to cover the code. You can obtain 100% coverage with this approach. Note that you don't need to add any real logic to your test, the generated code just needs the return type created and any related types referenced.

This is the pattern used in the blog...

@IsTest
private with sharing class wwwUpsComWsdlXoltwsXavV10Test
{
    private class WebServiceMockImpl implements WebServiceMock
    {
        public void doInvoke(
            Object stub, Object request, Map<String, Object> response,
            String endpoint, String soapAction, String requestName,
            String responseNS, String responseName, String responseType)
        {
            if(request instanceof wwwUpsComXmlschemaXoltwsXavV10.XAVRequest_element)
                response.put('response_x', new wwwUpsComXmlschemaXoltwsXavV10.XAVResponse_element());
            return;
        }
    }
}

@IsTest
private with sharing class wwwUpsComWsdlXoltwsXavV10Test
{
    private static testMethod void coverMethods()
    {
        new wwwUpsComWsdlXoltwsXavV10.XAVPort().ProcessXAV(null, null, null, null);
    }
}

Then for each type add line in the following test method...

@IsTest
private with sharing class wwwUpsComWsdlXoltwsXavV10Test
{
    private static testMethod void coverTypes()
    {
        new wwwUpsComXmlschemaXoltwsCommonV10.TransactionReferenceType();
    }
}

Its currently hand coded, however I've been recently playing around with native Apex parsing and code generation with the Tooling API. Though once you get a copy paste flow going from the generated code to the test methods it can be done quite quickly tbh.

Hope this helps...

  • 1
    Thanks Andy. It's not quite the zero-effort approach I'm looking for, but I think this is clear enough that I can run with it. I found this fully realized example from your blog post particularly useful: github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/… – Travis Dec 27 '13 at 15:14
  • wsdl is garbage, stop making services this way and you're life will be much easier. Create REST services which has been done for years now and you get plain old objects back via json, stop dealing with this wsdl soap garbage. It's the devil, you can't test it unless you write a crap load of ugly horrible code to try to mock it – WeDoTDD.com Dec 2 '14 at 2:06
  • 4
    @MSSucks Most people agree SOAP isn't amazing, but unless the development of every webservice on the Internet is under your control, sometimes you still have to implement and integration for them. – doublesharp Nov 24 '15 at 19:24
3

The FuseIT SFDC Explorer was recently extended to generate Apex classes that were compatible with the output of Wsdl2Apex.

Part of this includes the option to generate the required test methods and the corresponding WebServiceMock. These are currently only intended to give you sufficient code coverage for the generated code. Over time we may extend it further to make integration tests easier using the mock.

Full disclosure: I work for the company that releases this product. It is free to download and use.

0

I see no point in unit testing auto-generated code that only implements an interface for data exchange (data structures + bindings) and no logic at all. It's better to test a business code that uses these interfaces, by developing relevant Web Service Mocks. This way:

  • generated code is formally fully covered by unit tests,
  • business logic is really covered by unit tests.

Note: I noticed that Salesforce doesn't count coverage of inner classes unless an outer class is instantiated at least once - calling MyWebService ws = new MyWebService() at a beginning of an unit test resolves the issue. Possibly Salesforce has resolved this bug already in Winter '14.

  • 1
    I'm new to Apex, so this understanding comes only from looking at the docs, but it looks like in order to implement this approach, I would need to create a separate WebServiceMockImpl class for each type of response object, then still need to write a separate test method for each method in the imported class. That still seems like I'm basically just writing tests for this entire class, which is what I want to avoid. Is that correct? Is there any way around doing that, so I can just get the class deployed? – Travis Dec 27 '13 at 0:31
  • @Travis Imagine that you're sending your Accounts to an external webservice every time an Account is updated. Luckily code for connecting with that webservice is generated for free using wsdl2apex. But still you need a custom logic to listen for Account changes and call the class generated from WSDL, and that code should be unit tested. What I'm trying to convince is that you won't test your code well without implementing WebServiceMock and when you do it, the auto-generated code will be tested for free. – endrju Dec 27 '13 at 16:44

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.