Чтобы избежать повторения ===, вы можете использовать массив целевых значений и проверить, соответствует ли элемент какому-либо из целевых значений
const values = ["CRD_CRE_INS","CRD_EEA_BRA"]
this.entityTypes = codeList.Values.filter(c => values.includes(c.CodeValue));
Я не думаю, что Вы пропускаете любое волшебство, и я думаю, осуществляя рефакторинг для удаления кода персистентности из бизнес-объектов, и в персистентность слой является правильным способом пойти и от поблочного тестирования и от перспективы дизайна. Можно хотеть думать о наличии кэша, находятся между бизнес-слоем и слоем персистентности, добиваясь извлечения/обновления бизнес-объектов для упрощения вещей. Необходимо смочь дразнить/фальсифицировать кэш и слой персистентности при разделении вещей этот путь.
Код поблочного тестирования, который действительно датирует обработку на основе сегодняшней даты
Прежде
После
Эти два набора кода не должны зависеть друг от друга.
public static Func<string, UserName> Loader {get;set;}
public static Constructor()
{
Loader = GetFromDataBase;
}
public static User GetUser(string userName)
{
User user = GetUserFromCache()
if (user == null)
{
user = Loader(userName);
StoreUserInCache(user);
}
return user;
}
public void Test1()
{
UserGetter.Loader = Mock.GetUser;
UserGetter.GetUser("Bob");
}
Классически, интерфейс использовался бы вместо Func. Если больше чем один метод включен, интерфейс является очевидным выбором по Func. Если сами реализации методов статичны, Func является способом сделать абстракцию по ним.
Смотрите на Рефакторинг статического метода / статическое поле для Тестирования
Подход, предложенный там, может работать на Вас, если по некоторым причинам Вы не можете осуществить рефакторинг все для разделения проблем, как предложено в другом ответе.
То, что я пропускаю в Вашем примере, является контекстом Вашего вызова к "GetUser". Это, вероятно, потому что со статическим методом Вы не должны думать о том, как можно назвать его отовсюду. В DI это означает потребности репозитория ссылаться отправителем в некотором роде, поле, скорее всего.
Когда Ваш кэш является полем некоторого объекта, фасадом, вероятно, Вы могли использовать, это делает Ваш кэш прокси Вашей базы данных.
Таким образом, Вы имели бы:
class ApplicationFacade{
private IUserRepository users = null;
public doStuff(){
this.users.GetUser("my-name");
}
}
где IUserRepository является единым интерфейсом для Вашего кэша, поддельной базы данных и базы данных. Что-то простое как:
interface IUserRepository{
User GetUser(string username);
}
Ваш кэш мог теперь быть простым объектом, реализовав этот интерфейс и потому что кэш введен, контейнер DI может также ввести в него.
class Cache : IUserRepository {
private IUserRepository users = null;
public User GetUser(string username){
if (this.NotCached(username)){
this.ToCache(this.users.GetUser(username));
}
return this.FromCache(username);
}
}
Теперь в зависимости от то, что Вы хотите Вас, может ввести Вашу фальшивку, кэш или базу данных в Ваш объект фасада и если Вы используете свой объект кэша, что можно ввести фальшивку er база данных в него, как желаемый (или даже другой кэш, если Вы действительно хотели к).
Из причины фактический инжекционный механизм зависит от Вашего контейнера DI и может потребовать некоторого дополнительного кода как полей конструктора или общественных собственностей.