Skip to main content

模拟类

模拟类

ES6中所提供的class本质上是一个语法糖,背后实际上是一个构造函数,因此在对类进行测试的时候,可以使用jest.mock或者jest.spyOn来进行模拟测试。

如下是两个类,后续的所有测试用例将围绕此展开:

export default class ProductReview {
private _name: string
private _review: string

constructor(name: string, review: string) {
this._name = name
this._review = review
}

get name(): string {
return this._name
}

get review(): string {
return this._review
}
}

模拟构造器

在测试一个模块的时候,如果这个模块依赖了其它模块,为了屏蔽其影响,需要模拟一个完整的依赖,这种情况下可通过jest.mock方法来完成。

在上述示例中ReviewCollector依赖ProductReview,因此可以模拟ProductReview

import ReviewCollector from '../src/class/reviewCollector'
import ProductReview from '../src/class/productReview'

jest.mock('../src/class/productReview', () => {
return jest
.fn()
.mockImplementation(
(name: string, review: string) => {
return {
name,
review
}
}
)
})

基本测试

describe('Test ReviewCollector', () => {
let collector: ReviewCollector

beforeEach(() => {
collector = new ReviewCollector()
})

test('Add a review', () => {
const review = new ProductReview(
'Product A',
'Good'
)
collector.addReview(review)

expect(collector.getNumGoodReview('Product A')).toBe(1)
expect(collector.productList).toContain('Product A')
})

test('Get good review', () => {
const review1 = new ProductReview('Product A','Bad')
const review2 = new ProductReview('Product A','Good')
const review3 = new ProductReview('Product B','Good')

collector.addReview(review1)
collector.addReview(review2)
collector.addReview(review3)

expect(collector.getNumGoodReview('Product A')).toBe(1)
expect(collector.getNumGoodReview('Product B')).toBe(1)
})
})

模拟方法

通过jest.spyOn监听某个方法的调用:

const ReviewCollectorMock = jest
.spyOn(ReviewCollector.prototype, 'logReview')
.mockImplementation(() => 'Loged Review')

test('Test methods', () => {
const collector = new ReviewCollector()
const review = new ProductReview('Product A', 'Good')
collector.addReview(review)

collector.logReview()
expect(ReviewCollectorMock).toHaveBeenCalledTimes(1)
})

模拟静态方法

静态方法与实例方法类似:

const ReviewCollectorStaticMock = jest
.spyOn(ReviewCollector, 'showInfo')
.mockImplementation(() => 'Static method')

test('Test static methods', () => {
const result = ReviewCollector.showInfo()
expect(ReviewCollectorStaticMock).toHaveBeenCalled()
expect(result).toBe('Static method')
})

getter/setter

const ReviewCollectorSetterGetterMock = jest.spyOn(
ReviewCollector.prototype,
'productList',
'get'
)

test('Test getter', () => {
const collector = new ReviewCollector()
const review = new ProductReview('Product A', 'Good')
collector.addReview(review)
expect(ReviewCollectorSetterGetterMock).toHaveBeenCalled()
expect(collector.productList).toEqual(['Product A'])
})

模拟非默认导出

如果类不是默认导出,那么需要返回一个具有与类导出名称相同的键的对象:

jest.mock('../src/class/productReview', () => {
return {
ProductReview: jest
.fn()
.mockImplementation(
(name: string, review: string) => {
return {
name,
review
}
}
)
}
})