最终的 Kotlin 类不能被嘲笑,因为方法"should return Validator"



我正在尝试为我的 Javalin.io Web应用程序编写单元测试。有一些对 Mockito 的引用用于模拟 Context 对象,这是 Javalins 让用户访问传入的 Web 请求的方式。我试图模拟Context类的.header(String)方法,因为被测试单元正在读取"授权"标头并对其执行 JWT 检查。

我的pom包含一个最新版本的Mockito,它应该能够模拟期末课程:

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.2.0</version>
<scope>test</scope>
</dependency>

我已经启用了内联模拟制作器,如 Mockito 文档中所述,方法是使用内容mock-maker-inline创建文件resources/mockito-extensions/org.mockito.plugins.MockMaker

现在我有一个愚蠢的测试,它模拟一个Context对象,并且每当调用上下文对象的 header(( 方法时都应该返回"hello123"。以下代码是实际单元测试的一部分,但足以在运行测试时导致异常:

@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命令时。

我可以在本地重现该问题。 似乎在类加载过程中存在问题,Mockito每次都找不到正确的方法。 您可以按如下方式更改测试,以确保它找到正确的标头方法。它在我当地工作。

@Test
public void stupidTest1() {
Context context = mock(Context.class);
String test1 = "hello123";
Validator<String> f = new Validator<String>("hello123","Value");
when(context.header(test1,String.class)).thenReturn(f);
}
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"))
}
}

我在这里尝试了几个建议,但无法始终如一地让 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");
}

相关内容

最新更新