Можно ли писать методы, специально предназначенные для модульного тестирования? - PullRequest
0 голосов
/ 17 апреля 2020

Я выполняю рефакторинг своего кода, чтобы разрешить модульное тестирование (преобразование локальных переменных в параметры).

У меня есть определенный метод, который использует временный объект. (Этот объект должен быть заново создан для использования методом). Этот метод вызывает другой метод, который также использует временный объект.

public User GetUser(string id){
  MyContext db = new MyDbFactory.CreateDbContext();
  User user = db.Users.Find(id);
  return PopulateUser(user);
}

Я реорганизовал вышеизложенное в следующее:

public User GetUser(string id, MyContext db = null){
  if(db == null) db = new MyDbFactory.CreateDbContext();
  User user = db.Users.Find(id);
  return PopulateUser(user);
}

Я уже чувствую себя странно, но метод PopulateUser() также использует временный объект. Поэтому я реорганизовал его из этого:

public User PopulateUser(User user){
  MyContext db = MyDbFactory.CreateDbContext();
  //fill up user properties from join tables
  return user;
}

в следующее:

public User PopulateUser(User user, MyContext db = null){
  if(db == null) db = MyDbFactory.CreateDbContext();
  //fill up user properties from join tables
  return user;
}

Теперь, чтобы протестировать метод GetUser(), похоже, мне придется что-то сделать по-другому из этого:

public User GetUser(string id, MyContext db = null){
  bool noDb = false;
  if(db == null) {
     db = new MyDbFactory.CreateDbContext();
     noDb = true
  }
  User user = db.Users.Find(id);
  return noDb ? PopulateUser(user, db) : PopulateUser(user);
}

Мне пришло в голову, что, если я свободен сделать это, я мог бы также сделать это:

public User GetUser(string id, MyContext db = null, bool isTesting){
  if(!isTesting) {
     db = new MyDbFactory.CreateDbContext();
  }
  User user = db.Users.Find(id);
  return isTesting ? PopulateUser(user, db) : PopulateUser(user);
}

И это просто кажется мне неправильным. Начнем с того, что PopulateUser() не может использовать новую базу данных для тестирования, но я полагаю, проблем не будет, поскольку база данных тестирования находится в памяти. Теперь весь метод сильно отличается и кажется, что он был написан для тестирования.

Возможно, моя проблема в разделении проблем? Эти методы находятся в UserRepository, который используется UserController. UserRepository реализует интерфейс IUserRepository, который я буду использовать для проверки поведения контроллера, но сейчас я тестирую конкретный класс. Я должен, потому что он содержит логи, связанные с БД c.

Так что я делаю не так? Если ничего, то можно ли так реорганизовать мои методы?

...