Mockito cannot mock, mvn install fails
Сдаюсь. )) Как бы я не пыталась все поправить, получается только хуже
Собирая проект, пишу:
- mvn clean compile - works fine
- mvn test - works fine
- mvn install - fails with following error:
[ERROR] Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 0.271 s <<< FAILURE! - in com.book.site.security.filter.JwtTokenFilterTest
[ERROR] testSuccessfulAuthentication Time elapsed: 0.254 s <<< ERROR!
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.book.site.security.jwt.JwtTokenProvider.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Java : 11
JVM vendor name : Oracle Corporation
JVM vendor version : 11.0.12+8-LTS-237
JVM name : Java HotSpot(TM) 64-Bit Server VM
JVM version : 11.0.12+8-LTS-237
JVM info : mixed mode
OS name : Windows 10
OS version : 10.0
Underlying exception : java.lang.IllegalArgumentException: Could not create type
Caused by: java.lang.IllegalArgumentException: Could not create type
Caused by: java.lang.NoClassDefFoundError: com/book/site/domain/model/UserRole
Caused by: java.lang.ClassNotFoundException: com.book.site.domain.model.UserRole
[ERROR] testTokenNull Time elapsed: 0.003 s <<< ERROR!
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.book.site.security.jwt.JwtTokenProvider.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Java : 11
JVM vendor name : Oracle Corporation
JVM vendor version : 11.0.12+8-LTS-237
JVM name : Java HotSpot(TM) 64-Bit Server VM
JVM version : 11.0.12+8-LTS-237
JVM info : mixed mode
OS name : Windows 10
OS version : 10.0
Underlying exception : java.lang.IllegalArgumentException: Could not create type
Caused by: java.lang.IllegalArgumentException: Could not create type
Caused by: java.lang.NoClassDefFoundError: com/book/site/domain/model/UserRole
Caused by: java.lang.ClassNotFoundException: com.book.site.domain.model.UserRole
[ERROR] testTokenInvalid Time elapsed: 0.002 s <<< ERROR!
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.book.site.security.jwt.JwtTokenProvider.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Java : 11
JVM vendor name : Oracle Corporation
JVM vendor version : 11.0.12+8-LTS-237
JVM name : Java HotSpot(TM) 64-Bit Server VM
JVM version : 11.0.12+8-LTS-237
JVM info : mixed mode
OS name : Windows 10
OS version : 10.0
Underlying exception : java.lang.IllegalArgumentException: Could not create type
Caused by: java.lang.IllegalArgumentException: Could not create type
Caused by: java.lang.NoClassDefFoundError: com/book/site/domain/model/UserRole
Caused by: java.lang.ClassNotFoundException: com.book.site.domain.model.UserRole
[INFO] Running com.book.site.security.jwt.JwtTokenProviderTest
[ERROR] Tests run: 7, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.556 s <<< FAILURE! - in com.book.site.security.jwt.JwtTokenProviderTest
[ERROR] testTokenCreation Time elapsed: 0.001 s <<< ERROR!
java.lang.NoClassDefFoundError: com/book/site/domain/model/UserRole
at com.book.site.security.jwt.JwtTokenProviderTest.testTokenCreation(JwtTokenProviderTest.java:53)
Caused by: java.lang.ClassNotFoundException: com.book.site.domain.model.UserRole
at com.book.site.security.jwt.JwtTokenProviderTest.testTokenCreation(JwtTokenProviderTest.java:53)
[INFO] Running com.book.site.security.jwt.JwtUserFactoryTest
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.001 s <<< FAILURE! - in com.book.site.security.jwt.JwtUserFactoryTest
[ERROR] testUserTransformation Time elapsed: 0 s <<< ERROR!
java.lang.NoClassDefFoundError: com/book/site/domain/model/User
at com.book.site.security.jwt.JwtUserFactoryTest.testUserTransformation(JwtUserFactoryTest.java:15)
Caused by: java.lang.ClassNotFoundException: com.book.site.domain.model.User
at com.book.site.security.jwt.JwtUserFactoryTest.testUserTransformation(JwtUserFactoryTest.java:15)
[INFO] Running com.book.site.security.jwt.JwtUserTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.01 s - in com.book.site.security.jwt.JwtUserTest
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR] JwtTokenFilterTest.testSuccessfulAuthentication ? Mockito
Mockito cannot mock...
[ERROR] JwtTokenFilterTest.testTokenInvalid ? Mockito
Mockito cannot mock this class:...
[ERROR] JwtTokenFilterTest.testTokenNull ? Mockito
Mockito cannot mock this class: cl...
[ERROR] JwtTokenProviderTest.testTokenCreation:53 NoClassDefFound com/book/site/domain...
[ERROR] JwtUserFactoryTest.testUserTransformation:15 ? NoClassDefFound com/book/site/d...
[INFO]
[ERROR] Tests run: 12, Failures: 0, Errors: 5, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for book-site 0.0.1-SNAPSHOT:
[INFO]
[INFO] book-site .......................................... SUCCESS [ 0.970 s]
[INFO] book-site-domain ................................... SUCCESS [ 0.962 s]
[INFO] book-site-service .................................. SUCCESS [ 1.839 s]
[INFO] book-site-security ................................. FAILURE [ 2.094 s]
[INFO] book-site-controller ............................... SKIPPED
[INFO] book-site-app ...................................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.105 s
[INFO] Finished at: 2021-11-13T20:32:21+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project book-site-security: There are test failures.
[ERROR]
[ERROR] Please refer to C:\Users\Анастасия\IdeaProjects\book-site\book-site-security\target\surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <args> -rf :book-site-security
Сначала я подумала, что это может из-за мокито инлайн, после чего все использование статических методов заменила на функциональные интерфейсы и зависимость удалила - но нет, падает с тем же
Вот тест класс:
package com.book.site.security.jwt;
import com.book.site.domain.model.UserRole;
import com.book.site.security.properties.JwtProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Date;
import static com.book.site.security.MockJwtUsersProvider.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class JwtTokenProviderTest {
private static final String SECRET_KEY = "secret";
private static final long EXPIRATION = 360000;
private static final String AUTH_HEADER = "Authorization";
private static final String ACCESS_TOKEN = "access-token-123";
@Mock
private JwtProperties properties;
@Mock
private UserDetailsService userDetailsService;
@InjectMocks
private JwtTokenProvider tokenProvider;
@Mock
private HttpServletRequest httpRequest;
@Test
public void testTokenCreation() {
when(properties.getExpired()).thenReturn(EXPIRATION);
when(properties.getSecret()).thenReturn(SECRET_KEY);
UserRole userRole = new UserRole();
userRole.setName(USER_ROLE_NAME);
String token = tokenProvider.createToken(USERNAME, userRole);
Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
assertEquals(USERNAME, claims.getSubject());
assertEquals(USER_ROLE_NAME, claims.get("role"));
}
@Test
@SuppressWarnings("all")
public void testGetAuthentication() {
JwtUser expectedUser = jwtUserProvider();
when(properties.getSecret()).thenReturn(SECRET_KEY);
when(userDetailsService.loadUserByUsername(USERNAME)).thenReturn(expectedUser);
Authentication authentication = tokenProvider.getAuth(testTokenProvider());
assertThat(authentication, is(instanceOf(UsernamePasswordAuthenticationToken.class)));
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
assertThat(userDetails, is(instanceOf(JwtUser.class)));
JwtUser actualUser = (JwtUser) userDetails;
assertEquals(expectedUser, actualUser);
assertTrue(((String) authentication.getCredentials()).isEmpty());
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
assertTrue(expectedUser.getAuthorities().containsAll(authorities));
}
@Test
public void testGetUsername() {
when(properties.getSecret()).thenReturn(SECRET_KEY);
String testToken = testTokenProvider();
String actualUsername = tokenProvider.getUsername(testToken);
assertEquals(USERNAME, actualUsername);
}
@Test
public void testRetrieveBearerToken() {
String bearerPrefix = "Bearer ";
when(httpRequest.getHeader(AUTH_HEADER)).thenReturn(bearerPrefix + ACCESS_TOKEN);
String actualToken = tokenProvider.retrieveToken(httpRequest);
assertEquals(ACCESS_TOKEN, actualToken);
}
@Test
public void testNotRetrieveOtherToken() {
String basicPrefix = "Basic ";
when(httpRequest.getHeader(AUTH_HEADER)).thenReturn(basicPrefix + ACCESS_TOKEN);
assertNull(tokenProvider.retrieveToken(httpRequest));
}
@Test
public void testValidToken() {
when(properties.getSecret()).thenReturn(SECRET_KEY);
String testToken = testTokenProvider();
assertTrue(tokenProvider.validateToken(testToken));
}
@Test
public void testInvalidToken() {
when(properties.getSecret()).thenReturn(SECRET_KEY);
String testToken = testTokenProvider(1);
Exception exception = assertThrows(JwtAuthException.class,
() -> tokenProvider.validateToken(testToken));
String expectedErrorMsg = "JWT token expired or invalid";
String actualErrorMsg = exception.getMessage();
assertEquals(expectedErrorMsg, actualErrorMsg);
}
private String testTokenProvider() {
return testTokenProvider(EXPIRATION);
}
private String testTokenProvider(long expiration) {
Claims claims = Jwts.claims().setSubject(USERNAME);
Date now = new Date();
Date validity = new Date(now.getTime() + expiration);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>book-site-app</module>
<module>book-site-controller</module>
<module>book-site-domain</module>
<module>book-site-service</module>
<module>book-site-security</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.books.site</groupId>
<artifactId>book-site</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>book-site</name>
<description>book-site</description>
<properties>
<java.version>11</java.version>
<testcontainers.version>1.16.0</testcontainers.version>
<jjwt.version>0.9.1</jjwt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
<mainClass>com.book.site.app.BookSiteApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
sub-pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>book-site</artifactId>
<groupId>com.books.site</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>book-site-security</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.books.site.service</groupId>
<artifactId>book-site-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
хочу отметить, что запуская класс SpringBoot, все работает замечательно
так же нормально работает если запускать из идеи
что может быть не так?