---
# System prepended metadata

title: 單元測試的 3 個撰寫方法

---

# 單元測試的 3 個撰寫方法

每個被測單元 (Unit) 的測試案例 (Test Case) 都有 3A 原則的 **Arrange, Act, Assert** 這 3 個階段。

### 方法 1 驗證目標物件的回傳值

![](https://i.imgur.com/zq36cVo.png)

```typescript
// return-value.ts
export const sum = (a, b) => a + b;

// return-value.spec.ts
import { sum } from './sum'

describe('sum()', () => {  // Unit
  it('return 2, when a = 1 b = 1', () => {  // Test case
    // Arrange
    const a = 1, b = 1;

    // Act
    const result = sum(a, b);

    // Assert 驗證 回傳值為預期結果
    expect(result).toEqual(2);
  });
});
```

### 方法 2 驗證目標物件的狀態改變

![](https://i.imgur.com/HmuYc0N.png)

```typescript
// state-change.ts
export const service = {
  c: 0,
  changeC = (v) => {
    this.c = v;
  },
};

// state-change.spec.ts
import { service } from './state-change'

describe('changeC()', () => {  // Unit
  it('c = 3, when v = 3', () => {  // Test case
    // Arrange
    const result = 3;

    // Act
    service.changeC(3);

    // Assert 驗證 service.c 狀態被改變
    expect(service.c).toEqual(result);
  });
});
```

### 方法 3 驗證目標物件與外部相依介面的互動方式

![](https://i.imgur.com/KRdN0F2.png)

```typescript
// interaction.ts
export const service = {
  getFromApi: () => 'data',
  data: null,
  setToStore: d => { this.data = d; },
  getData: () => {
    const d = this.getFromApi();
    this.setToStore(d);
    return d;
  }
};

// interaction.spec.ts
import { service } from './interaction'

describe('getData()', () => {  // Unit
  it('call sev.getFromApi(), sev.setToStore()', () => {  // Test case
    // Arrange 準備 被測單元相依的物件/行為
    const getFromApi = spyOn(service, 'getFromApi');  // 準備假的 getFromApi
    const setToStore = spyOn(service, 'setToStore');  // 準備假的 setToStore

    // Act 動作
    service.getData();  // 使用 getData

    // Assert 驗證 有使用相依的物件/行為
    expect(getFromApi).toHaveBeenCalled(); // 假的 getFromApi 應該要被 getData 使用
    expect(setToStore).toHaveBeenCalled(); // 假的 setToStore 應該要被 getData 使用
  });
});
```

### 對應 驗收測試 的格式
單元測試 的撰寫格式，也可以對應 驗收測試

| Acceptance Test | Unit Test |
| --------------- | --------- |
| Feature         | Unit      |
| Scenario        | Test Case |
| Given           | Arrange   |
| When            | Act       |
| Then            | Assert    |

### 總結

* 3A 原則: **Arrange, Act, Assert**
* 測試方法:
    * 驗證目標物件的 **回傳值**
    * 目標物件的 **狀態改變**
    * 目標物件與 **相依物件/行為的互動** 方式