您提供的有关Arrange Act Assert的链接说明了该模式的好处(已添加重点):
好处:
- ...
- 使一些 TestSmells 更加明显:
- 断言与“Act”代码混合。
- 尝试同时测试太多不同事物的测试方法
特别是如果您的目标是能够快速扫描断言,我认为您的示例最好分成两个测试用例:协作测试和对象状态如何变化的单独测试。
我实际上认为这里有第四步,专门针对协作测试,即Expect。Kiwi 允许您安排、预期、执行,OCMock
实际上需要您通过 requires 来添加第四个冗余的Assert步骤[mockThing verify]
。
我认为这将是设置这些测试的更好方法:
__block TestedClass *sut;
beforeAll(^{
sut = [[TestedClass alloc] initWithCollaborator:mockThing];
}
// Collaboration: Arrange, Expect, Act
it(@"sends someMessage to mockThing", ^{
// Arrange
Thing *mockThing = [CollaboratingClass mock];
// Expect
[[[mockThing should] receive] someMessage];
// Act
[mockArray someMethodInvolvingCollaborator];
}
// State: Arrange, Act, Assert
it(@"sets someProperty to the return value of someMethod", ^{
// Arrange
NSString *expectedString = @"foo";
Thing *mockThing = [CollaboratingClass mock];
[[mockThing stubAndReturn:expectedString] someMessage];
// Act
[mockArray someMethodInvolvingCollaborator];
// Assert
[[sut.someProperty should] equal:expectedString];
}
使用此设置获得的好处是,如果您需要基于协作者的返回值进行分支,您只需添加另一个测试,该测试someMethod
将返回不同的结果,并做出不同的断言:
it(@"sets someProperty to nil if someMethod returns baz", ^{
// Arrange
Thing *mockThing = [CollaboratingClass mock];
[[mockThing stubAndReturn:@"baz"] someMessage];
// Act
[mockArray someMethodInvolvingCollaborator];
// Assert
[sut.someProperty shouldBeNil];
}
最终,我认为 Kiwi 不要求我们参加verify
测试双打是在帮我们一个忙。