This question is a bit older, but I just ran into the same issue myself.
Maybe in June 2017 it was correct, what Keith C wrote, but today - API version 43 - the DefaultCurrencyIsoCode is writable in a multicurrency org.
However, in a single currency org the field does not exist, and currencies can only be changed org-wide.
@isTest
public class CurrencyTest {
@isTest
public static void testDefaultCurrenciesOnUsers() {
Set<String> objectFields = Schema.SObjectType.User.fields.getMap().keySet();
// This is for Multicurrency orgs
if(objectFields.contains('DefaultCurrencyIsoCode')) {
User u = new User(LastName = 'Tester1');
u.put('DefaultCurrencyIsoCode', 'USD');
insert u;
System.runAs(u) {
System.assertEquals('USD', UserInfo.getDefaultCurrency());
}
u = new User(LastName = 'Tester2');
u.put('DefaultCurrencyIsoCode', 'EUR');
insert u;
System.runAs(u) {
System.assertEquals('EUR', UserInfo.getDefaultCurrency());
}
}
else {
System.assert(false, 'You are not in a multi-currency org.');
}
}
}
DefaultCurrencyIsoCode
field on User Sobject. developer.salesforce.com/docs/atlas.en-us.api.meta/api/… this field seems like is updateable