我现在处于一种情况,我需要实现类似于Mockito流利语法的东西:
app.post('/contact', function(req, res, next) {
const username = res.data.username;
const password = res.data.password;
res.send('Login details: ' + username + ' / ' + password);
});
我花了大约10分钟来查看github上的源代码,却没有看到实现引用任意方法的基本模式。不知何故,模拟对象必须记录调用的方法,以及传递给它的参数,在when( mock.arbitraryMethod( arg1, matcher2 ) ).thenReturn( foo );
随后可以获得的某个缓冲区中(它不能“看到”模拟或方法,这将被热切地评估)预先);当你将匹配器传递给该方法而不是常规参数时,问题就会复杂化。
有人总结一下这个伎俩吗?
答案 0 :(得分:1)
首先,你的例子是错误的。
它应该是这样的:
when( mock.arbitraryMethod( eq(arg1), matcher2.match() ) ).thenReturn( foo );
现在让我们看看它是如何运作的。
eq(arg1)
和matcher2.match()
被调用。这两种方法的调用都存储在一些静态变量中(如调用历史列表)。mock.arbitraryMethod(...)
被调用。它是mock的方法,因此Mockito
拦截它并将其调用存储在历史中。when(...)
被调用。这里所有的魔法都是酿造的。它检查历史记录并将其存储在它返回的对象中(然后清除历史记录)。thenReturn
只需配置模拟行为方式。它引导我们使用一些限制Mockito
用法的规则,例如:
eq(...)
之类的东西,因为它不允许找出参数序列。doReturn(x).when(...)
答案 1 :(得分:1)
一些小代码可以帮助说明正在发生的事情,并带来一些令人惊讶的结果。您希望使用Mockito的方式(以及您应该使用Mockito的方式)通常看起来像这样:
@Test
public void whenClauseExplanation_v1() {
MyImpl myMock = mock(MyImpl.class);
when(myMock.getStringObj()).thenReturn("What In The World?");
assertThat(myMock.getStringObj()).isEqualToIgnoringCase("WHAT IN THE WORLD?");
}
但是,你可以拆开它实际调用的方式并看到一些令人惊讶的结果:
@Test
public void whenClauseExplanation_v2() {
// 1. The argument to when() is a method call on the mock object, the method being stubbed.
// 2. Argument gets evaluated before when() is invoked
// 3. Eval of method call on mock records the invocation and arguments in ThreadLocal storage
// 4. "when()" is invoked, pops the most recent recorded invocation
// 5. ".thenReturn()" stubs the method to return a specific value when a matching invocation is encountered
// To demonstrate this:
MyImpl myMock = mock(MyImpl.class);
myMock.getStringObj(); // primes the pump
when(null).thenReturn("What In The World?"); // Huh? passing null?
// The argument itself doesn't really matter! But ordinary usage ensures the invocation is recorded before "when()" is evaluated.
assertThat(myMock.getStringObj()).isEqualToIgnoringCase("WHAT IN THE WORLD?");
}
正如您所看到的,when()
的参数甚至不重要,除了为thenReturn()
的参数中提供的预期返回类型提供类型安全性