function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
IanM1963IanM1963 

Mileage Tracker

Hi,

 

I'm greatly enjoying my journey into developing Force applications. I am new to this but not to programming in general.

 

I am doing the MileageTracker work book and everything was fine until I started work on the Unit Tests.

 

My negative tests are in a try catch block identical to the tutorial - I even copied and pasted the code - it saves ok but when I run the test the test fails. I know the code should throw an exception but it is as though it is not being caught?

 

Here is what I see in the debug log...

=======================

00:18:50.419 (419341000)|EXCEPTION_THROWN|[99]|System.AssertException: Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []
00:18:50.419 (419562000)|FATAL_ERROR|System.AssertException: Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []

Class.MileageTrackertestSuite.runNegativeTestCases: line 99, column 13
External entry point

 

======================

 

So, my question is, has anyone else encountered this and how do I overcome it and get a green light on the test?

 

Many thanks,

 

Ian

Shashikant SharmaShashikant Sharma

Please provide your test method, you are facing some assertion failure and seems your assert in catch block is failing. Would like to see your code.

sfdcfoxsfdcfox

Your test method needs one of the two following code structures:

 

 

public static void testMethod test() {
  Milage_Request__c req = new Milage_Request__c(Name='Test',Miles__c=501);
  try {
    insert req;
  } catch(Exception e) {
    // Awesome, it failed correctly.
  }
}

 

However, that makes it a bit cumbersome to make sure you actually made it into your try-catch block. An elegant solution would be as follows:

 

 

public static void testMethod test() {
  Milage_Request__c req = new Milage_Request__c(Name='Test',Miles__c=501);
  Database.SaveResult sr = Database.insert(req,false);
  System.AssertEquals(sr.isSuccess(),false,'Insert should have failed.');
}

This allows you to assert that the expected behavior occurred. I'd recommend the documentation on the System and Database methods in the Apex Code Developer's Guide.

 

IanM1963IanM1963

Hi, thanks for such prompt replies. Here is the code I'm using...

 

 

 

static testMethod void runNegativeTestCases() {

      
       
        
       System.debug('Inserting a record with 501 miles... (negative test case)');
        
       Mileage__c testMiles3 = new Mileage__c( Miles__c = 501, Date__c = System.today() );
        
        try {
            insert testMiles3;
        } catch (DmlException e) {
            //Assert Error Message  
    
            System.assert( e.getMessage().contains('Insert failed. First exception on ' +
                'row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ' +
                'Mileage request exceeds daily limit(500): [Miles__c]'), 
                e.getMessage() );
                  
            //Assert field  
    
            System.assertEquals(Mileage__c.Miles__c, e.getDmlFields(0)[0]);
            
            //Assert Status Code  
    
            System.assertEquals('FIELD_CUSTOM_VALIDATION_EXCEPTION' , 
                                 e.getDmlStatusCode(0) );
        } //catch  
    
        
    
    } // runNegativeTestCases()

 

 

IanM1963IanM1963

OK so now I have been trying to get this code working for two days. I have tried numerous ways including a version of the code suggestions posted here. What concerns me most is that apparently, all examples of MileageTracker don't work when it comes to negative case testing. I would love to get to the bottom of this, not just for me but for all other newbies that must get stuck when an example simply doesn't work?

 

Does anyone know why it doesn't work? It is throwing an exception and then simply failing the test which I thought was the reason for the catch block, so that the exception can be caught and handled gracefully, thus passing the test for a successfullly thrown exception.

IanM1963IanM1963

Hi there, I have posted the code exactly as it is in the tutorial. I would be seriously grateful if you could help me get to the bottom of this, as I have said, it could be very helpful to a lot of newbies if it turns out that tutorial material is not working as it should?

Jon Mountjoy_Jon Mountjoy_

Ack, that's odd.  I'll take a look at that Ian - though I'm traveling right now.  I might even have written that test case you're using.....

Jon Mountjoy_Jon Mountjoy_

It looks like something has changed in the latest release, and the error message doesn't quite correlate with what was written in the test case.   In fact, the test case is a litttle brittle.

 

Note that your exception is System.AssertException.  In other words, the exception *is* being caught, and one of the asserts in the test is failing. 

 

In particular, look at the exception you got.  It says:

Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []

 

But if you look at the test you have, it checks that the message contains a string (e.getMessage().contains(....)). In fact, it expects a string "[Miles__c]" in the message, but if you look at your exception, it just returned "[]"  

 

So I guess a quick fix is to change the catch clause of your test to something much simpler, something like:

 

 

} catch (DmlException e) {
            //Assert Error Message  
    
            System.assert( e.getMessage().contains('Insert failed. First exception on ' +
                'row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ' +
                'Mileage request exceeds daily limit'), 
                e.getMessage() );
                  
} //catch

 

 

That should do it.

 

Jon

 

PS. I note the getDmlFields also fails, which is why I took those out.  I'm not sure why they're feeling, and I'll try and figure it out.