클래스간 의존성을 클래스 외부에서 주입하는 것
//users-service.js
const User = require('./User');
const UsersRepository = require('./users-repository');
async function getUsers() {
return UsersRepository.findAll();
}
async function addUser(userData) {
const user = new User(userData);
return UsersRepository.addUser(user);
}
module.exports = {
getUsers,
addUser
}
위의 코드를 보면, ./users-repository을 require했기 때문에 다른 곳에서 이들을 사용할 때 유동저으로 사용하지 못하고 결과 값이 정해지는 문제점을 볼 수 있다.
다른 곳에서 userRepository의 내용 말고 userDB에서 가져오고 싶어도 사용할 수 없다는 뜻이다.
const User = require('./User');
function UsersService(usersRepository) { // check here
async function getUsers() {
return usersRepository.findAll();
}
async function addUser(userData) {
const user = new User(userData);
return usersRepository.addUser(user);
}
return {
getUsers,
addUser
};
}
module.exports = UsersService
위의 코드로 고치면 다른 곳에서 UserService.getUsers(아무거나)를 통해 다양한 값을 주어
user.js, userRepository.js -> UserService(내부는 정해져 있음 무조건 userRepo)였던 부분을
user.js -> UserService(userDB)으로 바꿀 수 있다.
user.js -> UserService(userRepo)
user.js -> UserService(kakaoUserRepo)
user.js -> UserService(naverUserRepo)
user.js -> UserService(googleUserRepo)
의존성 주입의 장점은 테스트코드를 작성할 때 더 들어나게 된다.
위의 의존성 주입을 적용하지 않은 코드의 테스트 코드를 보면
const UsersRepository = require('./users-repository');
const UsersService = require('./users');
const sinon = require('sinon') ;
const assert = require('assert');
describe('Users service', () => {
it('gets users', async () => {
const users = [{
id: 1,
firstname: 'Joe',
lastname: 'Doe'
}];
sinon.stub(UsersRepository, 'findAll', () => {
return Promise.resolve(users)
});
assert.deepEqual(await UsersService.getUsers(), users);
});
});
서버 호출은 비용이 높은 작업이다.
이를 테스트하기 위해 위의 코드는 userRepository를 모킹하여 완전한 usersService를 만들어야 한다.
const UsersService = require('./users');
const assert = require('assert');
describe('Users service', () => {
it('gets users', async () => {
const users = [{
id: 1,
firstname: 'Joe',
lastname: 'Doe'
}];
const usersRepository = {
findAll: async () => {
return users
}
};
const usersService = new UsersService(usersRepository);
assert.deepEqual(await usersService.getUsers(), users);
});
});