less than 1 minute read

Mock

Mock的关键:接口

mock的字面意思就是literally模拟一个对象。在软件中,mock的重点在于:不要求完全实现一模一样的功能,只要实现相同的接口即可。

它的原理是:假设被mock的对象是某接口的实现类,那么如果我的mock对象也实现该接口,我在test中就可以使用这个mock对象平替原对象。

Mock的用途

重要:Mock的对象必然不是我们要测试的对象。

Mock可以抽离出一些访问速度慢/不稳定/难以掌控返回值的对象。

比如说要测试web api,我们可以mock db,测试一下db返回error时,api是否应该返回对应的状态码。比如db返回ErrNoRow时api应该返回404,否则返回500。

要在正常情况下db还是挺难返回不同的error的。但把db mock了之后就可以随意改db的返回值了。

mock对象虽然实现了一样的接口,但其函数返回值基本是dummy。但这是唯一的缺点。

mock的好处很多:我们可以mock函数的input,指定函数的output。我们还可以require每个函数被执行几次,等等。

gomock

gomock是一个mock代码生成器。具体来说就是为被mock的接口生成代码。

比如说我指定要为我的db:Store接口生成mock,它就会生成一个MockStore类并实现所有Store接口函数。

stub

mock stub就是调用mock函数时写的一段代码,可以mock函数的input,指定函数的output, require每个函数被执行几次,等等。

比如这段代码的意思是:store.GetAccount()这个函数,在input为(any, eq(acc.ID))的条件下必须只被调用一次,指定返回值为(db.Account{}, sql.ErrNoRows)。

store.EXPECT().
  GetAccount(gomock.Any(), gomock.Eq(account.ID)).
  Times(1).
  Return(db.Account{}, sql.ErrNoRows)

httptest

主要用的是一个recorder。它可以记录http调用的返回结果。

比如执行server.router.ServeHTTP(recorder, request)就可以执行request并且将结果记录在recorder