0

I have a custom object where record name is auto generated. In a test class I am creating a record of that object and then calling another method from another class where this record is being used. That method throws error saying "Argument cannot be null". The created record has no name (or null name).

I cannot do record.Name = 'Test' as it shows an error saying "Field is not writable".

Any idea why the record name is null in the test class and how I solve it?

Code:

@isTest
private class MyTestClass {
    private static testMethod void test() {
        CustomObj__c obj = new CustomObj__c();
        obj.Field1__c = 'value';
        //so on
        insert obj;

        Boolean flag = SomeClassThatUsesCustomObj.StaticMethod(obj);
        System.assertsEqual(true, flag);
    }
}

When the static method of the SomeClassThatUsesCustomObj is running, it needs the name of the obj record. But since it is auto number, it comes out to be null and hence throws an exception and the test class fails.

3
  • Can you share a snippet of the code? Nov 26 '15 at 17:40
  • I have added a sample code. Nov 28 '15 at 17:43
  • As specified in One of the answers below, you simply have to query again for the name field after doing the insert. Nov 28 '15 at 23:15
3

If you want to mock an SObject with an auto-number field pre-filled in, do the following

Foo__c foo = (Foo__c) Json.deserialize('{"name" : "abc"}',Foo__c.class);

This is an object in memory, not in the database. You can add additional fields to mock in the JSON string expression.

Note that the JSON value for "name" doesn't even have to adhere to the auto-number format for the object.

UPDATE - when you need to insert the mocked SObject

@isTest
private class MyTestClass {
    private static testMethod void test() {
        CustomObj__c obj = new CustomObj__c();
        obj.Field1__c = 'value';
        //so on
        insert obj;
        obj = [select id, field1__c, name from CustomObj__c where id = :obj.id LIMIT 1]; // add this line

        Boolean flag = SomeClassThatUsesCustomObj.StaticMethod(obj);
        System.assertsEqual(true, flag);
    }
}

Auto-number field values of mocked SObjects must be queried before they can be referenced later in the code path. Note that @FernandoGavinho had this answer first

5
  • So do I do this when I am creating the record in my test class? Foo__c foo = (Foo__c) Json.deserialize('{"name" : "abc"}',Foo__c.class); foo.field__c = 'value'; insert foo; then call the other class which uses foo? Nov 27 '15 at 6:14
  • no - technique only works if you are not inserting - I thought that was your issue. If inserting, do the insert and then query the record to get the value of the autonumber field(s) as @FernandoGavinho suggested
    – cropredy
    Nov 27 '15 at 15:35
  • I have added a sample code that explains my situation. Nov 28 '15 at 17:42
  • I updated my answer
    – cropredy
    Nov 28 '15 at 18:09
  • appreciate your help @crop1645 Nov 30 '15 at 4:41
1

I also had a similar problem with that field. I solved it by querying the name field after the insert

2
  • The solution works for you cause you might be manually supplying the name field to the calling method. In my case, I need to supply the entire record to a method where it is processed. Nov 26 '15 at 14:27
  • @codeinprogress - Then you need to either put the code that calls the static method in a trigger or query for the entire object then pass it to the code.
    – Eric
    Nov 28 '15 at 19:39

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.