提醒：Junit4 的 @Test 为 `org.junit.Test`，不要和 Junit5 的搞混了

### 1、主要扩展

| 扩展 | 说明 | 
| -------- | -------- | 
| SolonJUnit4ClassRunner 类     | 为 junit4 提供 Solon 的注入支持的运行类     | 
|   |   | 
| HttpTester 类     | 用于 Http 测试的基类     | 
| @SolonTest 注解     | 用于指定 Solon 的测试主类。无此注解时，则以当前类为测试主类      | 
| @Rollback 注解 | 用户测试时事务回滚用 |
| @Import 注解 | 用于导入测试所需的配置文件 |
| | |
| HttpTester 类     | 用于 Http 测试的基类     | 




### 2、使用示例

引入插件：（`solon-test-junit4`）

```xml
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-test-junit4</artifactId>
    <scope>test</scope>
</dependency>
```


#### a）使用 @Test 注解

即使用 junit 4 的原生能力

```java
import org.junit.Test;

public class DemoTest {
    @Test
    public void hello() {
        System.out.println("Hello " + userName);
    }
}
```


#### b）使用 @RunWith(SolonJUnit4ClassRunner.class)，增加 Solon 能力

当前类将做为 Solon 启动的主类。还可借助 @Import 导入其它的包或配置（顺带提示：@Import 只在 主类上 或者 @Configuration类 上有效）。

* 提供Solon能力支持


```java
import org.junit.Test;
import org.junit.runner.RunWith;

@Import(profiles = "classpath:demo/app.yml")
@RunWith(SolonJUnit4ClassRunner.class) 
public class DemoTest {

    @Inject("${user.name:world}")
    String userName;

    @Test
    public void hello() {
        System.out.println("Hello " + userName);
    }
}
```

* 提供Solon能力支持，并导扫描其它包

```java
import org.junit.Test;
import org.junit.runner.RunWith;

@Import(scanPackages = "demo.b")
@RunWith(SolonJUnit4ClassRunner.class) 
public class DemoTest {

    @Inject("${user.name:world}")
    String userName;

    @Test
    public void hello() {
        System.out.println("Hello " + userName);
    }
}
```

#### c）使用 @RunWith(SolonJUnit4ClassRunner.class) + @SolonTest 注解 [推荐]

通过 @SolonTest 注解，可指定其它类为启动主类并进行测试。

* 启动Solon应用，并进行http接口测试

```java
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(SolonJUnit4ClassRunner.class)
@SolonTest(webapp.TestApp.class) 
public class DemoTest extends HttpTester{

    @Inject
    UserService userService;

    @Test
    public void hello() {
        //测试注入的Service
        assert userService.hello("world").equals("hello world");
    }
    
    @Test
    public void demo1_run0() {
        //HttpTester 提供的请求本地 http 服务的接口
        assert path("/demo1/run0/?str=").get().equals("不是null(ok)");
    }
    
    @Test
    public void demo2_header() throws Exception {
        Map<String, String> map = new LinkedHashMap<>();
        map.put("address", "192.168.1.1:9373");
        map.put("service", "wateradmin");
        map.put("meta", "");
        map.put("check_type", "0");
        map.put("is_unstable", "0");
        map.put("check_url", "/_run/check/");

        assert path("/demo2/header/")
                .header("Water-Trace-Id", "")
                .header("Water-From", "wateradmin@192.168.1.1:9373")
                .data(map)
                .post()
                .equals("OK");
    }
}
```


* 启动Solon应用，并设定启动参数

```java
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(SolonJUnit4ClassRunner.class)
@SolonTest(value=webapp.TestApp.class, args="--server.port=9001") 
public class DemoTest extends HttpTester{

    @Inject
    UserService userService;

    @Test
    public void hello() {
        //测试注入的Service
        assert userService.hello("world").equals("hello world");
    }
}
```