昆明cms模板建站,wordpress局域网自定义域名,哔哩哔哩网页版怎么回到旧版,wordpress小程序 jwt怎么写单元测试#xff1f;
JUnit 简介
基本上每种语言和框架都有不错的单元测试框架和工具#xff0c;例如 Java 的 JUnit、Scala 的 ScalaTest、Python的 unittest、JavaScript 的 Jest 等。上面的例子都是基于 JUnit 的#xff0c;我们下面就简单介绍下 JUnit。
JUnit…怎么写单元测试
JUnit 简介
基本上每种语言和框架都有不错的单元测试框架和工具例如 Java 的 JUnit、Scala 的 ScalaTest、Python的 unittest、JavaScript 的 Jest 等。上面的例子都是基于 JUnit 的我们下面就简单介绍下 JUnit。
JUnit 里面每个 Test 注解的方法就是一个测试。Ignore 可以忽略一个测试。Before、BeforeClass、After、AfterClass 可以在测试执行前后插入一些通用的操作比如初始化和资源释放等等。
除了 assertEqualsJUnit 也支持不少其他的 assert 方法。例如 assertNull、assertArrayEquals、assertThrows、assertTimeout 等。另外也可以用第三方的 assert 库比如 Spring 的 Assert 或者 AssertJ。
除了可以测试普通的代码逻辑JUnit 也可以进行异常测试和时间测试。异常测试是测试某段代码必须抛指定的异常时间测试则是测试代码执行时间在一定范围内。
也可以对测试进行分组。例如可以分成 contractTest 、mockTest 和 unitTest通过参数指定执行某个分组的测试。
这里就不做过多介绍了想了解更多 JUnit 的可以去看 极客学院的 JUnit 教程 等资料。其他的单元测试框架基本功能都是大同小异。
使用测试 Double
狭义的单元测试我们是只测试单元本身。即使我们写的是广义的单元测试它依然可能依赖其他模块比如其他类的方法、第三方服务调用或者数据库查询等等造成我们无法很方便的测试被测系统或模块。这时我们就需要使用测试 Double 了。
如果细究的话测试 Double 分成好多种比如什么 Dummies、Fakes 等等。但我认为我们只要弄清两类就可以了也就是 Stub 和 Mock。
Stub
Stub 指那些包含了预定义好的数据并且在测试时返回给调用者的对象。Stub 常被用于我们不希望返回真实数据或者造成其他副作用的场景。
我们契约测试生成的、可以通过 spring cloud stubrunner 运行的 Stub Jar 就是一个 Stub。我们可以让 Stub 返回预设好的假数据然后在单元测试里就可以依赖这些数据对代码进行测试。例如我们可以让用户查询 Stub 根据参数里的用户 ID 返回认证用户和未认证用户然后我们就可以测试调用方在这两种情况下的处理逻辑了。
当然Stub 也可以不是远程服务而是另外一个类。所以我们经常说要针对接口编程因为这样我们就可以很容易的创建一个接口的 Stub 实现从而替换具体的类。
public class StubNameService implement NameService {
public String get(String userId) {
return ““Mock user name””;
}
}
public class UserServiceTest {
// UserService 依赖 NameService会调用其 get 方法
Inject
private UserService userService;
Test
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
userService.setNameService(new StubNameService());
String testName userService.getUserName(““SomeId””);
Assert.assertEquals(““Mock user name””, testName);
}
}
不过这样要实现很多 Stub 也是很麻烦的现在我们已经不需要自己创建 Stub 了因为有了各种 Mock 工具。
Mock
Mocks 指那些可以记录它们的调用信息的对象在测试断言中我们可以验证 Mocks 被进行了符合期望的调用。
Mock 和 Stub 的区别在于Stub 只是提供一些数据它并不进行验证或者只是基于状态做一些验证而 Mock 除了可以做 Stub 的事情也可以基于调用行为进行验证。比如说Mock 可以验证 Mock 接口被调用了不多不少正好两次并且调用的参数是期望的数值。
Java 里最常用的 Mock 工具就是 Mockito 了。我们来看一个简单的例子下面的 UserService 依赖 NameService。当我们测试 UserService 的时候我们希望隔离 NameService那么就可以创建一个 Mock 的 NameService 注入到 UserService 中在 Spring 里只需要用 Mock 和 InjectMocks 两个注解就可以完成了
public class UserServiceTest {
InjectMocks
private UserService userService;
Mock
private NameService nameService;
Test
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
Mockito.when(nameService.getUserName(““SomeId””)).thenReturn(““Mock user name””);
String testName userService.getUserName(““SomeId””);
Assert.assertEquals(““Mock user name””, testName);
Mockito.verify(nameService).getUserName(““SomeId””);
}
}
注意上面最后一行是验证 nameService 的 getUserName 被调用并且参数为 ““SomeId””。更多关于 Mockito 的内容可以参考 Mockito 的文档(
http://static.javadoc.io/org.mockito/mockito-core/2.9.0/org/mockito/Mockito.html)。
契约测试
契约测试会给每个服务生成一个 Stub可以用于调用方的单元集成测试。例如我们需要测试预约服务的预约操作而预约操作会调用用户服务去验证用户的一些基本信息比如医生是否认证等。
所以我们可以通过传入不同的用户 ID让契约 Stub 返回不同状态的用户数据从而验证不同的处理流程。例如正常的预约流程的测试用例可能是这样的。
RunWith(SpringJUnit4ClassRunner.class)
SpringBootTestAutoConfigureStubRunner(repositoryRoot““http://nexus_root””,
ids {“com.xingren.service:user-client-stubs:1.0.0:stubs:6565”})public class BookingTest {
// BookingService 会调用用户服务获取医生认证状态后进行不同的处理
Inject
private BookingService bookingService;
Test
public void testBooking() {
BookingForm form new BookingForm(
1,// doctorId
1// scheduleId
1001);// patientId
BookVO res bookingService.book(form);
assertTrue(res.id 0);
assertTrue(res.payStatus PayStatus.UN_PAY);
}
}
注意上面的 AutoConfigureStubRunner 注解就是设置并启动了用户服务 Stub当然在测试的时候我们需要把服务调用接口的 baseUrl 设置为http://localhost:6565。关于契约测试的更多内容请参考微服务环境下的集成测试探索一文。
TDD
简单说下 Test Driven Development也就是 TDD。左耳朵耗子就写了一篇TDD并不是看上去的那么美我就直接引用其介绍了。
其开发过程是从功能需求的test case开始先添加一个test case然后运行所有的test case看看有没有问题再实现test case所要测试的功能然后再运行test case查看是否有case失败然后重构代码再重复以上步骤。
其实严格的 TDD 流程实用性并不高左耳朵耗子本身也是持批判态度。但是对于接口定义比较明确的模块先写单元测试再写实现代码还是有很大好处的。因为目标清晰而且可以立刻得到反馈。
文章来源网络 版权归原作者所有
上文内容不用于商业目的如涉及知识产权问题请权利人联系小编我们将立即处理