Last active
December 15, 2015 04:08
-
-
Save micahlmartin/5198865 to your computer and use it in GitHub Desktop.
Example of code that's easier to test and code that's harder to test. Instance vs. Static.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Acceptable | |
// Use of IoC required now in two places: UserService and CoolService | |
public class UserRepository | |
{ | |
public User GetUserByID(long userID) | |
{ | |
//Get user from database | |
} | |
public void Save(User user) | |
{ | |
//Save user to database | |
} | |
} | |
public class UserService | |
{ | |
private UserRepository _userRepository; | |
public UserService(UserRepository userRepository) | |
{ | |
_userRepository = userRepository | |
} | |
public User GetUserByID(long userID) | |
{ | |
return _userRepository.GetUserByID(userID); | |
} | |
public void Save(User user) | |
{ | |
_userRepository.Save(user); | |
} | |
} | |
public class CoolService | |
{ | |
private UserService _userService; | |
public SomethingCool(UserService userService) | |
{ | |
_userService = userService; | |
} | |
public void MakeUserCool(long userID) | |
{ | |
var user = _userService.GetUserByID(userID) | |
user.IsCool = true; | |
_userService.Save(user); | |
} | |
} | |
[TestFixture] | |
public class TestCoolService | |
{ | |
[Test] | |
[ExpectedException(typeof(Exception))] | |
public void TestUserIsCool | |
{ | |
var userRepositoryMock = new UserRepositoryMock(); | |
var userService = new UserService(userRepositoryMock); | |
var coolService = new CoolService(userService); | |
//This will throw an exception if user is not cool | |
coolService.MakeUserCool(1); | |
} | |
private class UserRepositoryMock | |
{ | |
public override User GetUserByID(long userID) | |
{ | |
return new User { UserID = userID, IsCool = false }; | |
} | |
public override void Save(User user) | |
{ | |
if(!user.IsCool) | |
throw new Exception("Expected user to be cool"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Bad | |
// IoC required at the method level and still needed at the CoolService level. | |
// Too many extra hoops to jump through and test | |
public class UserService | |
{ | |
public static User GetUserByID(long userID) | |
{ | |
return GetUserByID(userID, new UserService()); | |
} | |
public static User GetUserByID(long userID, UserService userService) | |
{ | |
return userService.GetUserByID(userID); | |
} | |
public static void Save(User user) | |
{ | |
Save(user, new UserService()); | |
} | |
public static void Save(User user, UserService userService) | |
{ | |
userService.Save(user); | |
} | |
} | |
public class CoolService | |
{ | |
private UserService _userService; | |
public CoolService(UserService userService) | |
{ | |
_userService = userService; | |
} | |
public void MakeUserCool(long userID) | |
{ | |
var user = UserService.GetUserByID(userID, _userService) | |
user.IsCool = true; | |
UserService.Save(user, _userService); | |
} | |
} | |
[TestFixture] | |
public class TestCoolService | |
{ | |
[Test] | |
[ExpectedException(typeof(Exception))] | |
public void TestUserIsCool | |
{ | |
var userServiceMock = new UserServiceMock(); | |
var coolService = new CoolService(userServiceMock); | |
//This will throw an exception if user is not cool | |
coolService.MakeUserCool(1); | |
} | |
private class UserServiceMock | |
{ | |
public override User GetUserByID(long userID) | |
{ | |
return new User { UserID = userID, IsCool = false }; | |
} | |
public override void Save(User user) | |
{ | |
if(!user.IsCool) | |
throw new Exception("Expected user to be cool"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Best | |
// Use of IoC is relegated only to the calling class. | |
// Only 1 point of indirection | |
public class UserService | |
{ | |
public virtual User GetUserByID(long userID) | |
{ | |
//Get user from database | |
} | |
public virtual void Save(User user) | |
{ | |
//Save user to database | |
} | |
} | |
public class CoolService | |
{ | |
private UserService _userService; | |
public SomethingCool(UserService userService) | |
{ | |
_userService = userService; | |
} | |
public void MakeUserCool(long userID) | |
{ | |
var user = _userService.GetUserByID(userID) | |
user.IsCool = true; | |
_userService.Save(user); | |
} | |
} | |
[TestFixture] | |
public class TestCoolService | |
{ | |
[Test] | |
[ExpectedException(typeof(Exception))] | |
public void TestUserIsCool | |
{ | |
var userServiceMock = new UserServiceMock(); | |
var coolService = new CoolService(userServiceMock); | |
//This will throw an exception if user is not cool | |
coolService.MakeUserCool(1); | |
} | |
private class UserServiceMock | |
{ | |
public override User GetUserByID(long userID) | |
{ | |
return new User { UserID = userID, IsCool = false }; | |
} | |
public override void Save(User user) | |
{ | |
if(!user.IsCool) | |
throw new Exception("Expected user to be cool"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Best 2 | |
// Use of IoC is relegated only to the calling class. | |
// Injection of dependency is through an instance variable rather than through the constructor | |
public class UserService | |
{ | |
public virtual User GetUserByID(long userID) | |
{ | |
//Get user from database | |
} | |
public virtual void Save(User user) | |
{ | |
//Save user to database | |
} | |
} | |
public class CoolService | |
{ | |
public UserService UserService { get; set; } | |
public void MakeUserCool(long userID) | |
{ | |
var user = UserService.GetUserByID(userID) | |
user.IsCool = true; | |
UserService.Save(user); | |
} | |
} | |
[TestFixture] | |
public class TestCoolService | |
{ | |
[Test] | |
[ExpectedException(typeof(Exception))] | |
public void TestUserIsCool | |
{ | |
var userServiceMock = new UserServiceMock(); | |
var coolService = new CoolService(); | |
coolService.UserService = userServiceMock; | |
//This will throw an exception if user is not cool | |
coolService.MakeUserCool(1); | |
} | |
private class UserServiceMock | |
{ | |
public override User GetUserByID(long userID) | |
{ | |
return new User { UserID = userID, IsCool = false }; | |
} | |
public override void Save(User user) | |
{ | |
if(!user.IsCool) | |
throw new Exception("Expected user to be cool"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment