我正在尝试为我的Javalin.io Web应用程序编写单元测试。 Mockito中有a few references用于模拟Context objects,这是Javalins方式,使用户可以访问传入的Web请求。我正在尝试模拟.header(String)
类的Context
方法,因为被测单元正在读取“ Authorization”标头并对其执行JWT检查。
我的pom包含Mockito的最新版本,should be able to mock final classes:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.2.0</version>
<scope>test</scope>
</dependency>
我已通过创建内容为resources/mockito-extensions/org.mockito.plugins.MockMaker
的文件mock-maker-inline
来启用Mockito文档中所述的嵌入式模拟程序。
现在,我有一个愚蠢的测试,它模拟Context
对象,并且每当调用上下文对象的header()方法时都应返回“ hello123”。以下代码是 real 单元测试的一部分,但足以在运行测试时引起异常:
@Test
void stupidTest1() {
Context context = mock(Context.class);
String test1 = "hello123";
when(context.header("Authorization")).thenReturn(test1);
}
并尝试了这个:
@Test
void stupidTest1() {
Context context = mock(Context.class);
String test1 = "hello123";
given(context.header("Authorization")).willReturn(test1);
}
使用mvn test
执行此测试失败,但例外:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
String cannot be returned by header()
header() should return Validator
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
at my.package.stupidTest1(JavalinTest.java:28)
我在做错什么吗?奇怪的一点是,测试有时有时可以成功运行,但是在大多数情况下会失败,尤其是连续运行mvn test
命令几次时。
答案 0 :(得分:1)
我可以在本地重现该问题。 看来在类加载期间存在问题,并且Mockito每次都找不到正确的method。 您可以按以下方式更改测试,以确保找到正确的标头方法。它在我本地工作。
With Range("A1").Validation
Debug.Print .Formula1 '>> =LST_VIC
.Modify Formula1:=Replace(.Formula1, "VIC", "QLD")
Debug.Print .Formula1 '>> =LST_QLD
End With
答案 1 :(得分:0)
open class Context{
fun header(name: String) : String {
var token = "DEFAULT TOKEN"
if(name == "AUTHORIZATION"){
token = "Bearer 01234"
}
return token
}
}
测试类:
open class ContextTest {
var context: Context = mock()
@Test
fun testContextWhenHeaderIsAuth(){
/* Return what the real method returns.*/
whenever(context.header("AUTHORIZATION")).thenCallRealMethod()
assertEquals("Bearer 01234", context.header("AUTHORIZATION"))
/* Mocking the return value to be something you need*/
whenever(context.header("AUTHORIZATION")).thenReturn("Bearer XXX")
assertEquals("Bearer XXX", context.header("AUTHORIZATION"))
}
}
答案 2 :(得分:0)
我在这里尝试了几个建议,但无法始终如一地让 Mockito 与 io.javalin.http.Context 一起工作。它会工作一段时间然后停止工作。或者它可以在调试器中运行,但在正常执行时不起作用。
@Mobigital 的建议对我有用。
模拟 HttpServletRequest 和 HttpServletResponse。
@Test
public void get_csv() throws SQLException
{
final HttpServletRequest request= mock(HttpServletRequest.class);
final HttpServletResponse response = mock(HttpServletResponse.class);
final Map<Class<?>, ?> map = new LinkedHashMap<>();
// Mocking the Context was not working correctly.
// https://stackoverflow.com/questions/61792392/final-kotlin-class-can-not-be-mocked-because-method-should-return-validator
Context ctx = new Context(request, response, map);
when(request.getAttribute("database")).thenReturn(getConnection());
when(request.getHeader(Header.ACCEPT)).thenReturn("text/csv");
when(request.getQueryString()).thenReturn("my_param=some_value");
LocationGroupController controller = new LocationGroupController(new MetricRegistry());
controller.getAll(ctx);
verify(response).setStatus(200);
verify(response).setContentType("text/csv");
}