2.6 调用特定对象的方法

通常,声明了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 调用特定对象的方法)