仕事でJMockit戦闘

導入JMockit

プロジェクトPOMファイル、プラグインの設定を追加

<plugin> 
    <groupId>com.ctrip.flight.testframework.tools</groupId>
    <artifactId>ut-maven-plugin</artifactId>
    <version>2.2.4</version>
    <executions>
        <execution>
            <phase>none</phase>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

依存の導入(乱用しないようにするため)

<dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.37</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

API

2つのAPI、モックアップのセットと期待を持っているJMockit


new Expectations() {
	{
		instance.XXX();
		result = T;
	} 
}

モックアップ

基本的な使い方:

new MockUp<T>() {
        @Mock
        Object XXXXX() {
        	return obj
		}
} 

例:
IDependインタフェース既存:

public interface IDepend {
    String getName(Object obj);

    void doSomething(Object obj1,Object obj2);
}

実装クラスA:

public class DependA implements IDepend {
    @Override
    public String getName(Object obj) {
        return "A";
    }

    @Override
    public void doSomething(Object obj1, Object obj2) {
        System.out.println("A Do Something");
    }
}

実装クラスB:

public class DependB implements  IDepend {
    @Override
    public String getName(Object obj) {
        return "B";
    }

    @Override
    public void doSomething(Object obj1, Object obj2) {
        System.out.println("B Do Something");
    }
}

カテゴリをテストするには:

public class Service {

    private IDepend dependA = new DependA();

    public String serviceGetName() {
        doSamething();
        return dependA.getName(new Object());
    }

    private void serviceDoSamething() {
        dependA.doSomething(new Object(), new Object());
    }
}

1.Serviceモック自身serviceDoSamething

new MockUp<Service>() {
       @Mock
       void serviceDoSamething() {
   	}
} 

2.ServiceモックDependA的doSomethingの/のgetName

new MockUp<DependA>() {
		@Mock
		String getName(Object obj){
			// 当代码执行到dependA.getName(new Object())时,返回值为"Mock"
			return "Mock";
		}
        @Mock
        void serviceDoSamething() {
		}
} 

3.Mockは、すべての実装クラスDependA、DependB IDependから継承されました

public static <T extends IDepend> void doMock() {
    new MockUp<T>() {
     	@Mock
		String getName(Object obj){
		   	// 可以根据入参obj的不同,返回不同的结果
			if (obj == null )  {
				return "Mock A";
			}
			else return "Mock B";
		}
        @Mock
        void serviceDoSamething() {
		}
    };
}

モック外部/自分をサポートして4.MockUP公共、保護された、プライベート、静的この方法は、メソッドのシグネチャ+ @モックのコメントを使用して、同書を使用します。
5.Mockコンストラクタ

class T{
	public T(){
		System.out.println("init1");
		System.out.println("init2");
		System.out.println("init3");
	}
}

执行Mock:
new MockUp<T>{
	@Mock
	 void $init(){
		// $init会对T的构造器进行拦截,原有构造器执行3次打印,拦截之后,只会执行一次"init"的打印
		System.out.println("init");
	}
}

6.シミュレーション操作AOP

new MockUp<T>{
	@Mock
	Object $advice(Invocation invocation) {
		// $advice 会拦截所有请求
		System.out.println("执行AOP逻辑");
		// 继续调用方法
		return invocation.proceed()
	}
}

7.MockUp実装原理
ここに画像を挿入説明
ここに画像を挿入説明
JVMベースのダイナミックローディング機構(> = 1.6であるためにJavaバージョン)は、元のクラスのオブジェクトバイナリコードの変更により、仮想再クラスオブジェクトは、ソース・コード・レベルに等しい、方法は、置換されています。

期待

モックアップは非常に強力な、すべての可能なシナリオのほとんど毎日の仕事をサポートしていますが、我々はなど、新しいパラメータ、変更されたメソッド名、などのコードを変更する場合、元のテストコードは、認知することができないではないメソッドのシグネチャが一致したため、最後の仕上げUTの実行に失敗しました。

モッククラスDependAなる前に:

class DependA{
	public String test(int index, Object obj){
		XXX;
	}
}

1.Mockクラス/インスタンス

  • モッククラス(クラスのすべてのインスタンスは、モックです)
	@Mocked
	DependA instance ; //此处不使用@Mocked,直接new 一个实例也是可以的
	
	new Expectations(DependA.class){
            instance.test(anyint , withInstance(DependA));
        }
  • モックの例(単なる一例モッククラスは、他の実施例は、模擬入力しません)
@Mocked
	DependA instance ; //此处不使用@Mocked,直接new 一个实例也是可以的
	
	new Expectations(instance){
            instance.test(anyint , withInstance(DependA));
        }

注:上記の2つのケースが一の期待クラスは、入力パラメータ、クラスの具体的な例です。
基準試験方法、anyint、anyString、(クラス)に任意の、withInstance(クラス)... 期待は親からのもので、そのメンバ変数とメソッド定義呼び出し(要約)、
条件に応じて異なる結果を返す2.Mock
キーワードを:委任
要件:参照インデックスに応じて異なる値を返す必要が、そのようなインデックス= 0、リターンヌル、他の復帰「テスト」として

	@Mocked
	DependA instance ;
	
	 new Expectations(VisaActionImpl.class) {
            {
                testInstance.test(anyInt, (Object) any);
                result = new Delegate() {
                    String testMock(int index, Object obj) { // 注意此处自定义的deleage方法名称,不需要与被代理方法名称一致,但是参数必须一致
                       return index == 0 ? null : "test"; //当测试用例index,传参为0时,DependA的test方法返回值即为null,其他情况则返回“test”
                    }
                };
            }
        };

3.Mockインタフェース
IDependインターフェイス既存。

public interface Idepend {
    public String test();
}

现需对所有Idepend的实例的test方法进行mock:

@Capturing
Idepend testInstance;

new Expectations(){
            testInstance.test();
            result = "test";
        }

4.Returns
キーワードを返しますが、データのセットを受け取ることがあり、その結果は、条に従って順序シーケンスで返すことができます

new Expectations(){
            testInstance.test();
            Returns("1","2","3");
        }

試験方法は、「2」、「3」、「1」に続く行三のモック戻り値で3回呼び出されたとき

参考資料

http://jmockit.cn

リリース元の4件の記事 ウォンの賞賛1 ビュー154

おすすめ

転載: blog.csdn.net/weixin_36510400/article/details/104905969