Иногда в Salesforce тестирует Вас, должен создать Пользовательские объекты для выполнения части теста как speciifc тип пользователя.
Однако с Лета Salesforce 08 обновлений, попытки создать и Пользовательские объекты и обычные объекты (такие как Учетные записи) в том же контрольном выводе к следующей ошибке:
MIXED_DML_OPERATION, операция DML на объекте установки не разрешена после обновления объекта неустановки (или наоборот): Пользователь, исходный объект: Учетная запись
Обратите внимание, что ошибки не происходит, когда Вы запускаете тесты из Eclipse/Force.com IDE, но это действительно происходит, когда Вы развертываетесь к Salesforce и затем запускаете тесты из Salesforce.
Как я переписываю свои тесты для предотвращения этой ошибки?
Вот простой пример теста, который вызывает ошибку:
static testMethod void test_mixed_dmlbug() {
Profile p = [select id from profile where name='(some profile)'];
UserRole r = [Select id from userrole where name='(some role)'];
User u = new User(alias = 'standt', email='standarduser@testorg.com',
emailencodingkey='UTF-8', lastname='Testing',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='standarduser@testorg.com');
Account a = new Account(Firstname='Terry', Lastname='Testperson');
insert a;
System.runAs(u) {
a.PersonEmail = 'test@madeupaddress.com';
update a;
}
}
Думаю, здесь еще не так много сотрудников Salesforce.
Я нашел решение, не знаю, почему оно работает, но оно работает.
Все части теста, которые обращаются к обычным объектам, должны быть заключены в System.runAs, который явно использует текущего пользователя, например:
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
// put test setup code in here
}
Итак, пример метода text_mixed_dmlbug, приведенный в вопросе, будет выглядеть следующим образом:
static testMethod void test_mixed_dmlbug() {
User u;
Account a;
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
Profile p = [select id from profile where name='(some profile)'];
UserRole r = [Select id from userrole where name='(some role)'];
u = new User(alias = 'standt', email='standarduser@testorg.com',
emailencodingkey='UTF-8', lastname='Testing',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='standarduser@testorg.com');
a = new Account(Firstname='Terry', Lastname='Testperson');
insert a;
}
System.runAs(u) {
a.PersonEmail = 'test@madeupaddress.com';
update a;
}
}
Тогда ошибки MIXED_DML_OPERATION перестают возникать.
Похоже, вы нашли обходной путь . Я просто хотел попытаться выяснить, почему вы получили эту ошибку.
Думаю, вы столкнулись с этой проблемой (согласно http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm ):
sObjects, которые не могут Совместное использование в операциях DML
Некоторые объекты sObject требуют, чтобы вы выполняли операции DML только с одним типом для каждой транзакции. Например, вы не можете вставить учетную запись, а затем вставить пользователя или члена группы в одну транзакцию. Следующие объекты sObject не могут использоваться вместе в транзакции:
* Group1 * GroupMember * QueueSObject * User2 * UserRole * UserTerritory * Territory
Важно. Основное исключение для - это когда вы используете метод runAs в тесте.
Кроме того, в примечаниях к выпуску Summer 08 (эта ссылка представляет собой PDF-файл) говорится:
В предыдущих выпусках в одной транзакции , которая включала триггеры, {{1} } вы можете выполнять операции DML с более чем одним типом sObject, например , вы можете вставить учетную запись, затем вставить пользователя. Начиная с лета '08, вы можете выполнять операции DML только с одним типом sObject из следующего списка sObject.
Например, вы не можете вставить учетную запись , затем добавить пользователя или обновить группу, а затем вставить члена группы .
- Группа
- GroupMember
- QueueSObject
- Пользователь
- UserRole
- UserTerritory
- Territory
Кроме того, теперь User и Territory поддерживают вставку и обновление DML { {1}}, а UserRole теперь поддерживает операции вставки, обновления, удаления и обновления DML.
Операции Apex DML не поддерживаются для следующих sObjects:
- AccountTerritoryAssignmentRule
- AccountTerritoryAssignmentRuleItem
- UserAccountTeamMember