Home>

SpringBoot creates and tests a mapper test class using Mybatis
I want to test and see if I can actually get the value
* DB is in-memory H2

Test fails with autowired mapper null 1
* You can access the Autowired Mapper as much as you start Spring Boot and execute it.

When starting JUNIT, the following message is displayed and it fails.

java.lang.NullPointerException
    at com.example.demo.SampleRepositoryTest2.contextLoads (SampleRepositoryTest2.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at
Corresponding source code

Test class

package com.example.demo;
import java.util.Optional;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.demo.repository.SampleRepository;
import com.example.demo.repository.entity.Todo;
@SpringBootTest (classes = SampleRepositoryTest2.class)
@MybatisTest
public class SampleRepositoryTest2 {
    @Autowired
    private SampleRepository repo;
    @Test
    public void contextLoads () throws Exception {
        Optional<Todo>todo = repo.findById (1);
        Assertions.assertEquals (todo.get (). getTodoTitle (), "Make dinner");
    }
}

Repository

package com.example.demo.repository;
import java.util.List;
import java.util.Optional;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import org.springframework.stereotype.Repository;
import com.example.demo.repository.entity.Todo;
@Mapper
public interface SampleRepository {
    @Select ("select todo_id, todo_title, finished, created_at from todo where todo_id = # {id}")
    Optional<Todo>findById (Integer id);
    @Select ("select todo_id, todo_title, finished, created_at from todo")
    List<Todo>findAll ();
    @Select ("SELECT COUNT (*) FROM todo WHERE finished = # {finished}")
    long countByFinished (boolean finished);
    @Insert ("insert into todo (todo_id, todo_title, finished, created_at) values ​​(# {todoId},

# {todoTitle},

 # {finished},

 # {created_at}) ")")
    void insert (Todo to do);
}

\ src \ main \ resources \ data.sql

INSERT INTO todo (todo_id, todo_title, finished, created_at) VALUES (1,'Make breakfast', false, '2020-12-01 09:15:00');
INSERT INTO todo (todo_id, todo_title, finished, created_at) VALUES (2,'Make dinner', false, '2020-12-01 09:15:00');

\ src \ main \ resources \ schema.sql

create table if not exists todo (
    todo_id int,
    todo_title varchar (30),
    finished boolean,
    created_at timestamp
);

build.gradle

plugins {
    id'org.springframework.boot' version '2.3.2.RELEASE'
    id'io.spring.dependency-management' version '1.0.9.RELEASE'
    id'java'
}
group ='com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
    mavenCentral ()
}
ext {
    set ('springCloudVersion', "Hoxton.SR7")
}dependencies {
    implementation'org.springframework.boot: spring-boot-starter-cache'
    implementation'org.springframework.boot: spring-boot-starter-data-redis'
    implementation'org.springframework.boot: spring-boot-starter-data-jdbc'
    implementation'org.springframework.boot: spring-boot-starter-security'
    implementation'org.springframework.boot: spring-boot-starter-thymeleaf'
    implementation'org.springframework.boot: spring-boot-starter-web'
    implementation'org.springframework.boot: spring-boot-starter-data-rest'
    implementation'org.mybatis.spring.boot: mybatis-spring-boot-starter: 2.1.3'
    implementation'org.springframework.cloud: spring-cloud-starter-config'
    implementation'org.springframework.boot: spring-boot-starter-actuator'
    developmentOnly'org.springframework.boot: spring-boot-devtools'
    runtimeOnly'com.h2database: h2'
// implementation'com.github.springtestdbunit: spring-test-dbunit: 1.3.0'
// implementation'org.dbunit: dbunit: 2.5.1'
    testImplementation'org.springframework.boot: spring-boot-starter-test'
    testImplementation'org.mybatis.spring.boot: mybatis-spring-boot-starter-test: 2.1.3'
    testImplementation'org.springframework.security: spring-security-test'
    compileOnly ("org.project lombok: lombok")
}
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud: spring-cloud-dependencies: ${springCloudVersion}"
    }
}
test {
    useJUnitPlatform ()
}

Package configuration

What I tried

In build.gradle, modified the version of mybatis test library as follows.

http://mybatis.org/spring-boot-starter/mybatis-spring-boot-test-autoconfigure/
Checking the formula of mybatis, SpringBoot2.1 and above, because the version of the test library of mybatis was specified as 2.1

Before correction

implementation'org.mybatis.spring.boot: mybatis-spring-boot-starter-test: 1.3.4'


Revised

testImplementation'org.mybatis.spring.boot: mybatis-spring-boot-starter-test: 2.1.3'
Supplementary information (FW/tool version, etc.)

IDE
Spring Tool Suite Version: 3.9.7.RELEASE

  • Answer # 1

    If you're using mybatis-spring-boot-starter-test: 2.1.3, you can simplify it a bit.

    Also, the class set in @SpringBootTest is "Setting class name for Spring", so it is not necessary in this case.

    If you use JUnit4 series, write @RunWith (SpringRunner.class).
    When using JUnit5 series, it is not necessary to describe @RunWith.

    See "Using @MybatisTest on JUnit 5" at http://mybatis.org/spring-boot-starter/mybatis-spring-boot-test-autoconfigure/.

    @MybatisTest
    public class SampleRepositoryTest2 {
        @Autowired
        SampleRepository repo;
        @Test
        public void contextLoads () throws Exception {
            Optional<Todo>todo = repo.findById (1);
            Assertions.assertEquals (todo.get (). getTodoTitle (), "Make dinner");
        }
    }

  • Answer # 2

    Autowired should not be DI unless Spring is running,

    @RunWith (SpringRunner.class)

    Does it work without it?

    How @SpringBootTest automatically detects configurations-Qiita

  • Answer # 3

    In the first place, it was supposed that the DI container would start when the test was started, but it was not started, so when I created a new test class, it worked fine. (The cause of this is unknown)

    * In the Mybatis test, I was able to confirm that it can be tested only with "@MybatisTest" by deleting unnecessary annotations.