2024년 7월 7일 일요일

vuejs simple clean architecture -now is testing...-

 



### 1. 프로젝트 설정


먼저 프로젝트 디렉토리를 생성하고 필요한 패키지를 설치


```bash

mkdir vue-clean-architecture

cd vue-clean-architecture

npm init -y

npm install vue vuex inversify reflect-metadata jest @vue/test-utils vue-jest

```


### 2. 프로젝트 구조


다음과 같은 프로젝트 구조 생성


```

vue-clean-architecture/

├── src/

│   ├── components/

│   │   └── MyComponent.vue

│   ├── entities/

│   │   └── User.js

│   ├── repositories/

│   │   └── UserRepository.js

│   ├── usecases/

│   │   └── GetUserUseCase.js

│   ├── container.js

│   ├── main.js

├── tests/

│   ├── repositories/

│   │   └── UserRepository.spec.js

│   ├── usecases/

│   │   └── GetUserUseCase.spec.js

│   └── MyComponent.spec.js

├── package.json

└── jest.config.js

```


### 3. 코드 작성


#### `src/entities/User.js`


```javascript

class User {

  constructor(id, name) {

    this.id = id;

    this.name = name;

  }

}


module.exports = User;

```


#### `src/repositories/UserRepository.js`


```javascript

const { injectable } = require('inversify');

const User = require('../entities/User');


@injectable()

class UserRepository {

  getUserById(id) {

    return new User(id, 'John Doe');

  }

}


module.exports = UserRepository;

```


#### `src/usecases/GetUserUseCase.js`


```javascript

const { injectable, inject } = require('inversify');

const UserRepository = require('../repositories/UserRepository');


@injectable()

class GetUserUseCase {

  constructor(@inject(UserRepository) userRepository) {

    this.userRepository = userRepository;

  }


  execute(id) {

    return this.userRepository.getUserById(id);

  }

}


module.exports = GetUserUseCase;

```


#### `src/container.js`


```javascript

require('reflect-metadata');

const { Container } = require('inversify');

const UserRepository = require('./repositories/UserRepository');

const GetUserUseCase = require('./usecases/GetUserUseCase');


const container = new Container();

container.bind(UserRepository).to(UserRepository);

container.bind(GetUserUseCase).to(GetUserUseCase);


module.exports = container;

```


#### `src/components/MyComponent.vue`


```vue

<template>

  <div>

    <p>{{ user.name }}</p>

  </div>

</template>


<script>

import { container } from '../container';

import GetUserUseCase from '../usecases/GetUserUseCase';

import User from '../entities/User';


export default {

  data() {

    return {

      user: new User(0, ''),

    };

  },

  created() {

    const getUserUseCase = container.get(GetUserUseCase);

    this.user = getUserUseCase.execute(1);

  },

};

</script>

```


### 4. Jest 설정 및 테스트 작성


#### `jest.config.js`


```javascript

module.exports = {

  preset: '@vue/cli-plugin-unit-jest',

  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],

  transform: {

    '^.+\\.vue$': 'vue-jest',

    '^.+\\.(js|jsx)$': 'babel-jest',

  },

  moduleNameMapper: {

    '^@/(.*)$': '<rootDir>/src/$1',

  },

};

```




### 2. 테스트 코드 작성


#### `tests/repositories/UserRepository.spec.js`


```javascript

const { container } = require('../../src/container');

const UserRepository = require('../../src/repositories/UserRepository');


describe('UserRepository', () => {

  it('should return a user by id', () => {

    const userRepository = container.get(UserRepository);

    const user = userRepository.getUserById(1);

    expect(user.id).toBe(1);

    expect(user.name).toBe('John Doe');

  });

});

```


#### `tests/usecases/GetUserUseCase.spec.js`


```javascript

const { container } = require('../../src/container');

const GetUserUseCase = require('../../src/usecases/GetUserUseCase');


describe('GetUserUseCase', () => {

  it('should return a user by id', () => {

    const getUserUseCase = container.get(GetUserUseCase);

    const user = getUserUseCase.execute(1);

    expect(user.id).toBe(1);

    expect(user.name).toBe('John Doe');

  });

});

```


#### `tests/MyComponent.spec.js` (이미 작성된 코드에서 변경 없음)


```javascript

import { shallowMount } from '@vue/test-utils';

import MyComponent from '@/components/MyComponent.vue';

import { container } from '@/container';

import GetUserUseCase from '@/usecases/GetUserUseCase';

import User from '@/entities/User';


test('displays user name', () => {

  const getUserUseCase = container.get(GetUserUseCase);

  jest.spyOn(getUserUseCase, 'execute').mockReturnValue(new User(1, 'John Doe'));


  const wrapper = shallowMount(MyComponent);

  expect(wrapper.text()).toContain('John Doe');

});

```


### 3. 테스트 실행


```bash

npm run test

```

0 comments:

댓글 쓰기