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
zen_njzen_nj 

any restrictions on apex code for User object - I can't write unit testing for it

Hi folks

I wanted to enforce the Users object (standard sf object) so that we can't have duplicate "Alias" entries since we key off certain reports and views based on the User Alias field.

I was able to write a basic trigger code and a basic public class to execute it. But when I try to write a testmethod for it, I am getting
all sorts of errors about not being able to do this and that with Users.

So, my trigger code is straight forward:
trigger UserAliasDuplicatePreventer on User (before insert, before update) {
EnsureUniqueUserData.checkUniqueUserAlias(Trigger.new);
}

And all it does is call on this apex class EnsureUniqueUserData and the method in it checkUniqueuserAlias.
And the logic works fine when I am just testing it out directly in sandbox by updating/creating new User entries with same Alias value.

public class EnsureUniqueUserData
{

public static void checkUniqueUserAlias (User[] users)
{
for (User u:users)
{
for (User Existusers : [select id,Alias,Name from User where Alias = :u.Alias])
{
// If there is a match
// System.assertEquals(Existusers.name,null);
u.addError('An User with this Alias already exists!');
}
}
}

static testmethod void testUniqueUserAlias()
{

User User1 = new User (Name = 'test user1', Alias = 'testu');
insert User1;
// make sure User is created
System.assert(User1.id != null);

// Now create a 2nd User entry that uses same Alias, it should fail
User User2 = new User (Name = 'test user2', Alias = 'testu');
insert User2;
// make sure User is created
System.assertEquals(User2.id,null);


// Now delete the 1st User entry with the testu alias and try again, it should work now

delete User1;
User User3 = new User (Name = 'test user3', Alias = 'testu');
insert User3;
// make sure User is created
System.assert(User3.id != null);
System.assertEquals(User3.Alias,'testu');

}


The problem is when I try to save the testmethod code, it complained with this:
Error: Compile Error: Field is not writeable: Name at line 20 column 34

I try to change my creation of user entry so that instead of:

User User1 = new User (Name = 'test user1', Alias = 'testu');
insert User1;

I just use:

User User1 = new User (Alias = 'testu');
insert User1;

But now it complains on the insert statement with message:
Error: Compile Error: DML not allowed on User at line 21 column 4


How  can I get this into production if the unit testing doesn't seem to be working properly (i.e. are there restrictions on the
Users object because that's how salesforce is essentially creating sf login)??

thx in advance for your help.
cajcaj
I am having the exact same issue attempting to insert a User object for the purpose of unit testing. Any ideas?
TehNrdTehNrd
The insert DML operation is not supported on the User object but the update operation is.

It is a good practice to create objects from scratch when testing but for User testing you need to query existing Users and test on them.


Message Edited by TehNrd on 05-07-2008 01:23 PM
zen_njzen_nj
Thx for the info about doing an update instead of creating a new user.
I tried to do this but am getting an error. Maybe I am not writing the code properly here?

My testmethod contains this:

static testmethod void testUniqueUserAlias()
{

User User2 = [select id,Alias,Name from User where Alias = 'good'];
// make sure User does exist with Alias of abc
System.assert(User2.id != null);

// also make sure that there is no user that has the Alias we are about to update User2 to

for (User TestUser2 : [select id,Alias,Name from User where Alias = 'good2'])
{
TestUser2.addError('An user with this Alias already exist!');
}

// Now update User2 to have a new Alias that we know doesn't exist

User2.Alias = 'good2';
update User2;

User UpdatedUser2 = [select id,Alias,Name from User where id = :User2.id];

// make sure User2 alias is updated. This should work since there is no dupe Alias being
// created yet by the update statement.
System.assertEquals(UpdatedUser2.Alias,'good2');

// and then the rest of the section would be actually doing an update to an Alias that we do know already exist.
.
.
.

}

However, when I run test on this, the test failed with the following error message:

System.Exception: Assertion Failed: Expected: good, Actual: good2.

I would think the update User2 statement worked since there was no trigger code failure. But somehow when I am
querying the supposed updated User2 entry and saving it as UpdatedUser2, the Alias field is still reflecting the original
User2.Alias value of 'good' instead of 'good2'.

So am I making a wrong assumption somewhere or the code is not properly written?


zen_njzen_nj
OK

Finally got it working. I had to revised my public class logic that the trigger is calling so that depending on if it's an insert or an update behavior, it will perform an additional check to test for situation where the trigger.old.Alias value is the same as trigger.new.Alias (and if it is, then don't fire off the trigger)

I was barely able to squeak by with 83% code coverage - I am guessing it's really because I couldn't test for situation where the insert logic is firing off since we can't issue insert on Users in the testmethod.

d3developerd3developer

This is an old thread but in case anyone comes across it:

 

You can insert a User.

 

You cannot insert a User and perform another DML operation in the same method.

 

Here is how to do both for testing.

 

test method:

 

test utility