2.6 调用特定对象的方法

作者: 孙兴斌 | 来源:发表于2016-12-27 17:34 被阅读27次

通常,声明了mock对象并在Expectation中进行了record,则在replay阶段对该类其他对象的调用也会返回record的结果。也就是说,在replay阶段,JMockit并不关心调用的是哪个对象,只要是该mock类的对象就会引用record中的结果。

示例如下:

@Test
public void TestMethod(@Mocked final Dependency dependency) throws Exception {
    new NonStrictExpectations() {{
        dependency.intReturnMethod();
        returns(1, 2, 3);
    }};

    Dependency dependency1 = new Dependency();
    assertEquals(1, dependency1.intReturnMethod());

    Dependency dependency2 = new Dependency();
    assertEquals(2, dependency2.intReturnMethod());

    Dependency dependency3 = new Dependency();
    assertEquals(3, dependency3.intReturnMethod());
}

在大多数情况下,CodeUnderTest使用mock类的某一个对象,所以是在CodeUnderTest中创建的还是作为参数传给它的并不重要。但是,如果CodeUnderTest中包含多个mock对象,而我们需要

  • 只mock其中某个对象,其它的并不mock
  • 指定调用某个mock对象的方法

这时,使用 @Injectable 可以mock某个对象。当然,即使用 @Mock 注解mock该类所有对象,也有其他方法限制Expectation中的匹配。


@Injectable

public class Dependency {
    public String mockMethod() {
        return "realMethod";
    }
}
@Test
public void TestMethod(@Injectable final Dependency mockDependency) {
    new NonStrictExpectations() {{
        mockDependency.mockMethod();
        result = "mockMethod";
    }};
    assertEquals("mockMethod", mockDependency.mockMethod());
    assertEquals("realMethod", new Dependency().mockMethod());
}

其他对象不受影响,正常执行原有代码。

note:

  • 需要将mock对象传递给CodeUnderTest
  • static方法和constructor无法被mock

声明多个mock对象

声明多个mock对象可以限制和Expectation的匹配。

示例如下:

//参数中的anotherDependency只是起到占位作用,不会被真正使用
@Test
public void TestMethod(@Mocked final Dependency mockDependency, 
                       @Mocked Dependency anotherDependency) {
    new NonStrictExpectations() {{
        mockDependency.mockMethod();
        result = "mockMethod";
    }};
    
    //这个会被mock
    assertEquals("mockMethod", mockDependency.mockMethod());
    
    //JMockit仍然拦截了这次调用,但是由于在Expectation中没有record,所以返回null
    assertNull("realMethod", new Dependency().mockMethod());
}

这种方法看起来比较奇怪,主要用于当CodeUnderTest中包含多个Dependency类的对象,而想要测试其中某个确定对象会被调用。


mock特定constructor产生的实例

有两种方式可以实现这个效果,方式1:

@Test
//mockDependency不会被使用
public void TestMethod(@Mocked Dependency mockDependency) {
    new NonStrictExpectations() {{
        Dependency dependency1 = new Dependency("dependency1");
        dependency1.mockMethod(); result="dependency1";
        Dependency dependency2 = new Dependency("dependency2");
        dependency2.mockMethod(); result="dependency2";
    }};
    
    //可以创建多个对象,会匹配到同一个Expectation
    assertEquals("dependency1", new Dependency("dependency1").mockMethod());
    assertEquals("dependency1", new Dependency("dependency1").mockMethod());
    
    assertEquals("dependency2", new Dependency("dependency2").mockMethod());
    
    //JMockit仍然拦截了这次调用,但是由于在Expectation中没有record,所以返回null
    assertNull(new Dependency("dependency2").mockMethod());
}

方式2:

@Test
public void TestMethod(@Mocked final Dependency mockDependency1,
                       @Mocked final Dependency mockDependency2) {
    new NonStrictExpectations() {{
        new Dependency("dependency1");
        result = mockDependency1;
        new Dependency("dependency2");
        result = mockDependency2;
        mockDependency1.mockMethod();
        result = "dependency1";
        mockDependency2.mockMethod();
        result = "dependency2";
    }};
    assertEquals("dependency1", new Dependency("dependency1").mockMethod());
    assertEquals("dependency1", new Dependency("dependency1").mockMethod());
    assertEquals("dependency2", new Dependency("dependency2").mockMethod());
    assertNull("dependency3", new Dependency("dependency3").mockMethod());
}

两种方法等效。

相关文章

  • 2.6 调用特定对象的方法

    通常,声明了mock对象并在Expectation中进行了record,则在replay阶段对该类其他对象的调用也...

  • 原生js封装call、apply、bind方法

       call方法   首先要了解call方法,在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充...

  • 观阮一峰老师js教程笔记

    1. js中并不是所有值都是对象 基本数据类型不是对象,没有方法和属性方法:是某个特定对象才能调用的函数属性:是隶...

  • 对象方法和类方法

    -对象方法 +类方法 调用对象方法必须先创建对象,在通过对象来调用。 类方法不依赖对象,使用对象名直接调用。 类方...

  • 学习途中之类方法和对象方法

    对象方法1、 对象方法/实例方法我们之前学习的方法就叫做对象方法.对象方法的调用必须要先创建对象,通过对象来调用....

  • 再论静态方法和类方法

    实例对象可以调用实例方法、类方法、静态方法 类对象只能调用类方法、静态方法

  • JVM - 方法调用和返回指令

    方法调用指令 以下四条指令用于方法调用: invokevirtual 指令用于调用对象的实例方法,根据对象的实际类...

  • flutter setState的调用链分析

    state对象 调用setState方法后,会调用对应的element对象的markNeedsBuild方法,标记...

  • OC重学第二天

    一. 类方法 OC 中方法分为两种.对象方法/实例方法如果想要调用对象方法必须要创建对象,通过对象来调用类方法.类...

  • 函数中this指向问题以及this四大绑定原则

    一、 普通调用方式 => window 构造函数调用=> 实例对象,原型对象里面的方法也指向实例对象 对象方法...

网友评论

    本文标题:2.6 调用特定对象的方法

    本文链接:https://www.haomeiwen.com/subject/dkdevttx.html