0%

认识一下你的测试替身

测试替身是用来在测试中取代真实对象的,很类似与电影里演员的特技替身。测试替身的所有分类通常会被称为”mocks”,但由于不同的测试替身有不同的使用场景,对TA们进行区分还是挺重要的。最重要的测试替身有stubs,mocks和fakes。
stub没有逻辑,只返回你让TA返回的值。当你需要一个对象返回一个特定值,以使待测代码到达某一确定状态时,可以使用stubs。尽管手写stubs挺简单的,但使用mock框架通常可以减少很多的样板代码。

1
2
3
4
5
6
7
8
// Pass in a stub that was created by a mocking framework.
AccessManager accessManager = new AccessManager(stubAuthenticationService);
// The user shouldn't have access when the authentication service returns false.
when(stubAuthenticationService.isAuthenticated(USER_ID)).thenReturn(false);
assertFalse(accessManager.userHasAccess(USER_ID));
// The user should have access when the authentication service returns true.
when(stubAuthenticationService.isAuthenticated(USER_ID)).thenReturn(true);
assertTrue(accessManager.userHasAccess(USER_ID));

Mock带有被调用方式的预期,如果没有通过那样方式被调用,则该测试应该失败。Mock是用来测试对象之间交互的,且在那些没有其他可见状态变化或返回值的场景下是非常合适的(比如,你的代码从磁盘读取数据,你希望保证只读一次磁盘,你可以用mock来验证该方法确实只赌了一次磁盘)。

1
2
3
4
5
6
// Pass in a mock that was created by a mocking framework.
AccessManager accessManager = new AccessManager(mockAuthenticationService);
accessManager.userHasAccess(USER_ID);
// The test should fail if accessManager.userHasAccess(USER_ID) didn't call
// mockAuthenticationService.isAuthenticated(USER_ID) or if it called it more than once.
verify(mockAuthenticationService).isAuthenticated(USER_ID);

fake不适用mock框架:它是API的一种轻量级实现,看起来就想真实实现一样,但不适合在生产环境运行(例如,一个内存数据库)。fake可以使用在那些无法使用真实实现来测试的场景(例如,如果真是实现太慢了,或者需要通过网络访问)。你不需要自己来实现fake,因为fake通常是被那些维护真实实现的人或团队维护的。
1
2
3
4
5
6
7
8
9
// Creating the fake is fast and easy.
AuthenticationService fakeAuthenticationService = new FakeAuthenticationService();
AccessManager accessManager = new AccessManager(fakeAuthenticationService);
// The user shouldn't have access since the authentication service doesn't
// know about the user.
assertFalse(accessManager.userHasAccess(USER_ID));
// The user should have access after it's added to the authentication service.
fakeAuthenticationService.addAuthenticatedUser(USER_ID);
assertTrue(accessManager.userHasAccess(USER_ID));

术语”测试替身”是Gerard Meszaros在《xUnit Test Patterns》一书中创造的。你可以在该书中找到更多关于测试替身的信息,或者该书的网站。你也可以在Martin Fowler的文章中找到对于不同测试替身的讨论。

文章翻译自:

https://testing.googleblog.com/2013/07/testing-on-toilet-know-your-test-doubles.html