mattaddy / SObjectFabricator

An SObject fabrication API to reduce database interactions and dependencies on triggers in Apex unit tests.
Other
89 stars 14 forks source link

Cloning Fabricated Object #24

Closed packocz closed 1 year ago

packocz commented 1 year ago

Not a bug or issue, merely a question. I think I am missing something fundamental here. Any help or suggestions would be awesome, thanks for this great package!

I'm trying to extend sfab_FabricatedSObject and one of the things I'm needing is for any "set" to produce a new clone (I want to be building many records with common values and stuff). I noticed that there is a handy protected constructor that seemed like the best thing to use to preserve anything that's been set already, be it a field or relationship.

@testVisible
    protected sfab_FabricatedSObject(Type sType, List<sfab_FabricatedSObjectNode> nodes) {
        ...
    }

So I added another public method to the class to produce a clone. The intention being that my wrapper class will use this every time I add/change something to the fabricated object.

public sfab_FabricatedSObject copy() {
        return new sfab_FabricatedSObject(this.sType, this.nodes.clone());
    }

However, things seem to break and the toSObject() method no longer works, failing with this error: System.JSONException: Apex Type unsupported in JSON: Schema.SObjectField

I was wondering if you have any ideas what I'm doing wrong there. I tried to follow what's going on with the serialisation, but I could not figure it out at all.

I demonstrate the problem with this little script using the extended version of sfab_FabricatedObject where a1 gets generated fine, but a2 does not. The toSObject() call fails with the error above.

Account a1 = (Account) new sfab_FabricatedSObject(Account.class).set('Id', '001000000000001').toSObject();
System.debug(a1);

Account a2 = (Account) new sfab_FabricatedSObject(Account.class).set('Id', '001000000000001').copy().toSObject();
System.debug(a2);
packocz commented 1 year ago

Please forget this! I've finally found the problem and of course it's me 😊

In my copy method I was passing this.nodes as a whole (or clone) which is a map into the constructor of the new instance. Didn't realise this and this way I was inadvertently calling a wrong constructor! This one public sfab_FabricatedSObject(Type sType, Map<String, Object> fields)

So making sure I work with a list of nodes then calls the right one: protected sfab_FabricatedSObject(Type sType, List<sfab_FabricatedSObjectNode> nodes) and all is well.

bobalicious commented 1 year ago

Apologies for not having responded to this. I didn't see the original message coming in.

Glad you managed to resolve the issue you were having.

On Fri, 25 Nov 2022, 16:51 Aleš Remta, @.***> wrote:

Closed #24 https://github.com/mattaddy/SObjectFabricator/issues/24 as completed.

— Reply to this email directly, view it on GitHub https://github.com/mattaddy/SObjectFabricator/issues/24#event-7894385063, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABRYYB7655O4VIBDKAGNQXTWKDVAJANCNFSM6AAAAAAR5PHWR4 . You are receiving this because you are subscribed to this thread.Message ID: @.*** com>