Skip to content

Instantly share code, notes, and snippets.

@dev-jonghoonpark
Last active August 8, 2023 03:36
Show Gist options
  • Save dev-jonghoonpark/4357c4f489d9a3fa218631353d288c78 to your computer and use it in GitHub Desktop.
Save dev-jonghoonpark/4357c4f489d9a3fa218631353d288c78 to your computer and use it in GitHub Desktop.
단위 테스트 - 7장 가치 있는 단위 테스트를 위한 리팩터링
public class User
{
public int UserId { get; private set;}
public string Email { get; private set; }
public UserType Type { get; private set; }
public void ChangeEmail(int userId, string newEmail)
{
object[] data = Database.GetUserById(userId);
UserId = userId,
Email = (string)data[1];
Type = (UserType)data[2];
if (Email == newEamil)
return;
object[] companyData = Database.GetCompany();
string companyDomainName = (string)companyData[0];
int numberOfEmployees = (int)companyData[1];
string emailDomain = newEmail.Split("@")[1];
bool isEmailCorporate = emailDomain == companyDomainName;
UserType newType = isEmailCorporate
? UserType.Employee
: UserType.Customer;
if (Type != newType) {
int delta = newType == UserType.Employee ? 1 : -1;
int newNumber = numberOfEmployees + delta;
Database.SaveCompany(newNumber);
}
Email = newEmail;
Type = newType;
Database.SaveUser(this);
MessageBus.SendEmailChangedMEssage(userId, newEmail);
}
}
public enum UserType
{
Customer = 1,
Employee = 2
}
// UserController : Line #17 에서 호출되는 부분
public int ChangeEmail(string newEmail, string companyDomainName, int numberOfEmployees)
{
if(Email == newEmail)
return numberOfEmployees;
string emailDomain = newEmail.Split("@")[1];
bool isEmailCorporate = emailDomain == companyDomainName;
UserType newType = isEmailCorporate
? UserType.Employee
: UserType.Customer;
if (Type != newType)
{
int delta = newType == UserType.Employee ? 1 : -1;
int newNumber = numberOfEmployees + delta;
Database.SaveCompany(newNumber);
}
Email = newEmail;
Type = newType;
return numberOfEmployees;
}
public class UserFactory
{
public static User Create(object[] data)
{
Precondition.Requires(data.Length >= 3);
int id = (int)data[0];
string email = (string)data[1];
UserType type = (UserType)data[2];
return new User(id, email, type);
}
}
public class Company
{
public string DomainName { get; private set; }
public int NumberOfEmployees { get; private set; }
public void ChangeNumberOfEmployees(int delta)
{
Precondition.Requires(NumberOfEmployees + delta >= 0);
NumberOfEmployees += delta;
}
public bool IsEmailCorporate(string email)
{
string emailDomain = email.Split('@')[1];
return emailDomain == DomainName;
}
}
public class UserController
{
private readonly Database _database = new Database();
private readonly MessageBus _messageBus = new MessageBus();
public void ChangeEmail(int userId, string newEmail)
{
object[] userData = _database.GetUserById(userId);
User user = UserFactory.Create(userData);
object[] companyData = _database.GetCompany();
Company company = CompanyFactory.Create(companyData);
user.ChangeEmail(newEmail, company);
_database.SaveCompany(company);
_database.SaveUser(user);
_messageBus.SendEmailChangedMEssage(userId, newEmail);
}
}
public class User
{
public int UserId { get; private set;}
public string Email { get; private set; }
public UserType Type { get; private set; }
public void ChangeEmail(string newEmail, Company company)
{
if (Email == newEamil)
return;
UserType newType = company.isEmailCorporate(newEmail)
? UserType.Employee
: UserType.Customer;
if (Type != newType)
{
int delta = newType == UserType.Employee ? 1 : -1;
int newNumber = numberOfEmployees + delta;
Database.SaveCompany(newNumber);
}
Email = newEmail;
Type = newType;
}
}
public class UserController
{
private readonly Database _database = new Database();
private readonly MessageBus _messageBus = new MessageBus();
public void ChangeEmail(int userId, string newEmail)
{
object[] data = _database.GetUserById(userId);
string email = (string)data[1];
UserType type = (UserType)data[2];
var user = new User(userId, email, type);
object[] companyData = _database.GetCompany();
string companyDomainName = (string)companyData[0];
int numberOfEmployees = (int)companyData[1];
int newNumberOIfEmployees = user.ChangeEmail(newEmail, companyDomainName, numberOfEmployees);
_database.SaveCompany(newNumberOIfEmployees);
_database.SaveUser(user);
_messageBus.SendEmailChangedMEssage(userId, newEmail);
}
}
[Fact]
public void Changing_email_from_non_corporate_to_corporate()
{
var company = new Company("mycorp.com", 1);
var sut = new User(1, "user@gmail.com", UserType.Customer);
sut.ChangeEmail("new@mycorp.com", company);
Assert.Equal(2, company.NumberOfEmployees);
Assert.Equal("new@mycorp.com", sut.Email);
Assert.Equal(UserType.Employee, sut.Type);
}
[InlineData("mycorp.com", "email@mycorp.com", true)]
[InlineData("mycorp.com", "email@gmail.com", false)]
[Theory]
public void Differentiates_a_corporate_email_from_non_corporate(
string domain, string email, bool expectedResult)
{
var sut = new Company(domain, 0);
bool isEmailCorporate = sut.IsEmailCorporate(email);
Assert.Equal(expectedResult, isEmailCorporate);
}
public string CanChangeEmail()
{
if (IsEmailConfirmed) {
return "Can't change a confirmed email";
}
return null;
}
public void ChangeEmail(string newEmail, Company company)
{
Precondition.Requires(CanChangeEmail() == null);
/* TODO */
}
public class EmailChanedEvent
{
public int UserID { get; }
public string NewEmail { get; }
}
public void ChangeEmail(string newEmail, Company company)
{
Precondition.Requires(CanChangeEmail() == null);
if (Email == newEmail)
return;
UserType newType = company.isEmailCorporate(newEmail)
? UserType.Employee
: UserType.Customer;
if (Type != newType)
{
int delta = newType == UserType.Employee ? 1 : -1;
company.ChangeNumberOfEmployees(delta);
}
Email = newEmail;
Type = newType;
EmailChangedEvents.Add(new EmailChangedEvent(UserId, newEmail));
}
public string ChangedEmail(int userId, string newEmail)
{
object[] userData = _database.GetUserById(userId);
User user = UserFactory.Create(userData);
string error = user.CanChangeEmail();
if (error != null)
return error;
object[] companyData = _database.getCompany();
Company company = CompanyFactory.Create(companyData);
user.ChangeEmail(newEmail, company);
_database.SaveCompany(company);
_database.SaveUser(user);
foreach (var ev in user.EmailChangedEvents) {
_messageBus.SendEmailChangedMessage(
ev.UserId, ev.NewEmail);
}
return "OK";
}
[Fact]
public void Changing_email_from_corporate_to_non_corporate()
{
var company = new Company("mycorp.com", 1)
var sut = new User(1, "user@mycorp.com", UserType.Employee, false);
sut.ChangeMail("new@gmail.com", company);
company.NumberOfEmployees.Should().Be(0);
sut.Email.Should().Be("new@gmail.com");
sut.Type.Should().Be(UserType.Customer);
sut.EmailChangedEvents.Should().Equal(new EmailChangedEvent(1, "new@gmail.com"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment