Here's a suggestion that may be of use to you that's based on the classic test helper class such as the one below which contains a few snippets of one I used recently for an org I was working in. I'll explain some suggested modifications at the end.
/**
* A collection of utilities and methods for use in unit tests.
* @author crmprogdev
*/
@isTest(seeAllData=true)
global class XXXX_Test_Helper_Util {
global PrimAdmin_CustSttng__c Admin {set;}
global PrimAdmin_CustSttng__c Admin1 {set;}
global TBA_CustSttng__c TBA {set;}
global EHcc_CustSttng__c CC1 {set;}
global Pub_Boolean_A__c BoolA {get;}
global Pub_Bool_B__c BoolB {get;}
global static void init() {
/* create our global settings object and set the defaults */
PrimAdmin_CustSttng__c Admin = generateTestPrimAdmin();
PrimAdmin_CustSttng__c Admin1 = generateTestPrimAdmin1();
EHcc_CustSttng__c CC1 = generateTestCC1();
User TBA_u = generateTBA();
TBA_CustSttng__c TBA = generateTestTBA(TBA_u);
}
/** a default user to use in System.runAs() */
private static User testRunner {
get {
if (null == testRunner) {
// all test code should execute under a user we can control so as to avoid
// surprises when deploying to different environments.
UserRole[] roles = [SELECT Id FROM UserRole WHERE DeveloperName = 'Admin'];
if (roles.isEmpty() == true) {
roles.add(new UserRole(DeveloperName = 'Admin', Name = 'r0'));
insert roles;
}
testRunner = new User(Alias = 'tstr01', Email='[email protected]', EmailEncodingKey='UTF-8', FirstName= 'TstrFrst', LastName='TstrLst01', LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey='America/Los_Angeles', UserName='[email protected]');
testRunner.UserRoleId = roles[0].Id;
insert testRunner;
}
return testRunner;
}
private set;
}
global static PrimAdmin_CustSttng__c generateTestPrimAdmin(){
PrimAdmin_CustSttng__c Admin = new PrimAdmin_CustSttng__c();
if (PrimAdmin_CustSttng__c.getValues('Admin') == null){
Admin.ContactName__c = 'Carey XXXX' ;
Admin.UserID__c = 'xxxxxxxxxx'; //(sandbox, prod)
Admin.UserName__c = '[email protected]';
Admin.Email__c = '[email protected]'; // [email protected]
Admin.Name = 'Admin';
upsert Admin;
}
else if (PrimAdmin_CustSttng__c.getValues('Admin') != null ){
Admin = PrimAdmin_CustSttng__c.getValues('Admin');
}
return Admin;
}
global static PrimAdmin_CustSttng__c generateTestPrimAdmin1(){
PrimAdmin_CustSttng__c Admin1 = new PrimAdmin_CustSttng__c();
if (PrimAdmin_CustSttng__c.getValues('Admin1') == null){
Admin1.ContactName__c = 'Steven XXXXX';
Admin1.UserID__c = xxxxxxxxxx; //(sandbox, prod)
Admin1.UserName__c = '[email protected]';
Admin1.Email__c = '[email protected]';
Admin1.Name = 'Admin1';
upsert Admin1;
}
else if (PrimAdmin_CustSttng__c.getValues('Admin1') != null ){
Admin1 = PrimAdmin_CustSttng__c.getValues('Admin1');
}
return Admin1;
}
global static EHcc_CustSttng__c generateTestCC1(){
EHcc_CustSttng__c CC1 = new EHcc_CustSttng__c();
if (EHcc_CustSttng__c.getValues('CC1') == null){
CC1.Name = 'CC1';
CC1.SendCC__c = true;
upsert CC1;
}
else if (EHcc_CustSttng__c.getValues('CC1') != null ){
CC1 = EHcc_CustSttng__c.getValues('CC1');
}
return CC1;
}
global static User generateTBA(){
User U0 = [SELECT Id, Name, email, Division, Title, UserRoleId, ProfileId, Username FROM User WHERE IsActive = True AND (Profile.DeveloperNameId = 'Admin' OR Profile.Id = 'FloridaAdmin') limit 1];
User U1 = [SELECT Id, Name, email, Division, Title, UserRoleId, ProfileId, Username FROM User WHERE IsActive = True AND (Profile.DeveloperNameId = 'SalesManager' OR Profile.Id = 'FloridaSalesManager') AND UserRole.Name = 'Project Manager' limit 1];
list<Account> TBAa = new list<Account>(); // TBA contact list
list<Id> TBAasrId = new list<Id>(); // TBAa insert results validation list
list<Contact> TBAc = new list<Contact>(); // TBA contact list
list<Id> TBAcsrId = new list<Id>(); // TBAc insert results validation list
list<User> TBAu = new list<User>(); // TBA user list
list<Id> TBAusrId = new list<Id>(); // TBAu insert results validation list
if(U0.Id == null ){
TBAu[0] = null;
} else
system.RunAs(U0){
/* create the TBA acct */
Account tbaact = new Account(Name = 'TBAact', Is_Active__c = true, Region__c = 'SouthEast', OwnerID = U1.Id );
TBAa.add(tbaact);
/* insert the new Accts */
if(TBAa.IsEmpty() == false)Insert TBAa;
/* Create the TBA contact */
Contact tbaCtc = new Contact( AccountID = TBAa[0].Id, LastName = 'TBAtst1', Phone = '777-755-0001', MailingStreet = '999 TBD St', MailingCity = 'TBA', MailingState = 'FL', Position__c = 'Ambassador', MobilePhone = '777-755-1001', RecordTypeId = '012400000005IeZAAU' );
TBAc.add(tbaCtc);
/* insert the tbaCtc */
if(TBAc.IsEmpty() == false) Insert(TBAc);
/* create the TBA user */
User tbaUsr = new User(ContactID = TBAc[0].Id, Alias = 'tbatst1', Email='[email protected]', EmailEncodingKey='UTF-8', LastName= TBAc[0].LastName, LanguageLocaleKey='en_US', LocaleSidKey='en_US', ProfileId = U5.ProfileId, MobilePhone = TBAc[0].MobilePhone, Phone = TBAc[0].Phone,TimeZoneSidKey='America/Los_Angeles', UserName='[email protected]');
TBAu.add(tbaUsr);
if(TBAu.IsEmpty() == false) Insert TBAu;
TBA_CustSttng__c TBA2 = new TBA_CustSttng__c();
TBA2 = Kube_Test_Helper_Util.generateTestTBA(TBAu[0]);
}
return TBAu[0];
}
public static TBA_CustSttng__c generateTestTBA(User TBA_u){
User TBAu = TBA_u;
TBA_CustSttng__c TBA1 = new TBA_CustSttng__c ();
if(null == TBA1){
TBA1.ContactID__c = TBAu.ContactId;
TBA1.ContactName__c = 'TBAtst1';
TBA1.CtcRecTypeID__c = '012400000005IeZAAU';
TBA1.UserID__c = TBAu.Id;
TBA1.UserName__c = TBAu.UserName;
TBA1.UserProfileID__c = TBAu.ProfileId;
TBA1.Email__c = TBAu.Email ;
TBA1.Name = 'TBA1';
upsert TBA1;
}
return TBA1;
}
}
You'll notice I've included a number of custom settings in the above. The custom settings that I'd want to be private would be:
PrimAdmin_CustSttng__c Admin {set;}
PrimAdmin_CustSttng__c Admin1 {set;}
TBA_CustSttng__c TBA {set;}
All of the above contain information about UserID's, email addresses, etc that you don't want to be visible to anyone else.
The custom settings to be set as public would be:
global EHcc_CustSttng__c CC1 {set;}
global Pub_Boolean_A__c BoolA {get;}
global Pub_Bool_B__c BoolB {get;}
The first one simply is used to set whether or not a CC is sent with an error handler message. The latter two are booleans that I've added for the purpose of answering this post. By using a strategy of setting Booleans in a Public Custom Setting, values could presumably be changed if the Boolean were set to True. So by altering the above code as below, I believe something like this could potentially work as a solution:
global static PrimAdmin_CustSttng__c generateTestPrimAdmin(){
PrimAdmin_CustSttng__c Admin = new PrimAdmin_CustSttng__c();
if (Pub_Boolean_A__c.getValues('BoolA') != null && BoolA.Value == 'true'){
Admin.ContactName__c = BoolA.ContactName__c ;
Admin.UserID__c = BoolA.UserID__c
Admin.UserName__c = BoolA.UserName__c;
Admin.Email__c = BoolA.Email__c; // [email protected]
Admin.Name = BoolA.Name;
upsert Admin;
}
else if (Pub_Boolean_A__c.getValues('BoolA') == null || BoolA.Value == 'false'){
Admin.ContactName__c = 'Carey XXXX' ;
Admin.UserID__c = 'xxxxxxxxxx'; //(sandbox, prod)
Admin.UserName__c = '[email protected]';
Admin.Email__c = '[email protected]'; // [email protected]
Admin.Name = 'Admin';
upsert Admin;
}
else if (PrimAdmin_CustSttng__c.getValues('Admin') != null ){
Admin = PrimAdmin_CustSttng__c.getValues('Admin');
}
return Admin;
}
It would seem to me that using this type of approach would allow a developer of managed packages
to have their private custom settings, yet also all them to "edit" them using public custom settings during development.
Note: I have not tested this, instead only taking the time to collect some snippets of code and modify them "on the fly" to present the concept for consideration. I do not develop "officially" managed packages as yet but can see where this approach would seem likely to prove fruitful. Obviously the runAs user in the code I presented would not be necessary. I included it to illustrate the source and context of the original code.
Protected
settings just behave asPublic
ones when part of a Beta install?