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, все работает замечательно

так же нормально работает если запускать из идеи

что может быть не так?


Ответы (0 шт):