当前位置: 首页 > 知识库问答 >
问题:

测试是否调用了其他方法

姜旭
2023-03-14

所以我肯定有类似的东西在那里,但我已经搜索了一个小时,还没有找到确切的我要找的东西。假设我有一个这样的类:

public class MyClass
{
    public void myMethod(boolean shouldCallOtherMethod)
    {
        if(shouldCallOtherMethod)
        {
            otherMethod();
        }
    }

    public void otherMethod()
    {
        System.out.println("Called");
    }
}

我该如何制作这样的作品?

@Test
public void shouldCallMethod()
{
    MyClass myClass = new MyClass();
    myClass.myMethod(true)

    // verify myClass.otherMethod method was called
}

共有3个答案

李昱
2023-03-14

不建议这样做,但您可以监视真实对象:)

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

import static org.mockito.BDDMockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Spy
    private MyClass sut; // System Under Test

    @Test
    public void shouldCallMethod() {

        // when
        sut.myMethod(true);

        // then
        verify(sut).otherMethod();
    }
}

结果:

Tests Passed: 1 passed in 0,203 s

更改代码后:sut.my方法(false);

Wanted but not invoked:
sut.otherMethod();
-> at my.custom.MyClassTest.shouldCallMethod(MyClassTest.java:23)

资料来源:监视真实物体

@Mock
private LexAnalyzer lexAnalyzer;

@Spy
@InjectMocks
private SyntaxAnalyzer sut; // System Under Test

@Test
public void shouldCallMethod() {

    // when
    sut.myMethod(true);

    // then
    verify(sut).otherMethod();
}
public class SyntaxAnalyzer {

    private final LexAnalyzer lexAnalyzer;

    public SyntaxAnalyzer(LexAnalyzer lexAnalyzer) {
        this.lexAnalyzer = lexAnalyzer;
    }
...

经过测试,有效;)

罗毅
2023-03-14

假设MokeysClass有一个这样声明的构造函数,其中Foo是其他类。

public MokeysClass(String name, int counter, Foo myFoo)

我会这样写我的测试。

@RunWith(MockitoJUnitRunner.class)
public class TestArray {
    @Mock 
    private Foo mockMyFoo;
    private String nameToInject = "Mokey";
    private int counterToInject = 42;

    @Spy 
    private MokeysClass toTest = new MokeysClass(nameToInject, counterToInject, mockMyFoo);

    @Test
    public void shouldCallMethod() {
        toTest.myMethod(true);
        verify(toTest).otherMethod();
    }
}

因此,我要明确说明在创建测试对象时要调用哪个构造函数,以及要传递给它的参数。

有一些理由不依赖@InjectMocks为我完成这一步,特别是当被测试的类更复杂并且有不止一个构造函数时。Mockito选择具有最多参数的构造函数,但是如果有几个构造函数具有相同数量的参数,Mockito可以选择任何构造函数;也就是说,行为是未定义的。

一旦Mockito选择了一个构造函数,它将检查该构造函数是否可以用于构造函数注入。不使用构造函数注入,如果

  • 所选构造函数的一个或多个参数是基元类型,
  • 所选构造函数的一个或多个参数的类型是最终类,
  • 所选构造函数的一个或多个参数的类型是私有类,
  • 该类的唯一构造函数是默认构造函数

如果其中任何一个条件成立,对于Mockito选择的构造函数,则不会使用构造函数注入。在这种情况下,该类必须具有默认构造函数,否则Mockito将引发异常

Mockito在选择是否应用构造函数注入时使用的标准的复杂性意味着添加或删除构造函数,或更改构造函数的参数,可以使Mockito从使用构造函数注入切换到使用setter和字段注入;或者从使用setter和field注入到使用构造函数注入。即使更改的构造函数不是将用于构造函数注入的构造函数,也可能发生这种情况。

因此,任何使用构造函数注入的测试都会自动变得非常脆弱;从某种意义上说,与测试本身没有直接关系的更改会导致测试失败。这样的故障很难排除。

@InjectMocks注释被设计用于执行依赖注入的框架,如Spring;对于使用Spring的类的测试,它可能是无价的。但是如果依赖注入不是类的一部分,我强烈建议避免@InjectMocks,因为它很脆弱。您确实希望您的测试代码像生产代码一样易于维护和故障排除。

寇夜洛
2023-03-14

使用Mockito,你可以监视真实的物体,比如:

import org.junit.Test;
import static org.mockito.Mockito.*;
public class MyClassTest {
    @Test
    public void otherMethodShouldBeCalled() {
        MyClass myClass = new MyClass();
        MyClass spy = spy(myClass);

        spy.myMethod(true);
        verify(spy).otherMethod();
    }
}

这里有一些陷阱,所以也可以看看相关的文档。

 类似资料:
  • 问题内容: 因此,我敢肯定那里有类似的东西,但是我一直在寻找一个小时,却没有找到我真正想要的东西。说我有一堂课,看起来像这样: 我该如何做这样的工作? 问题答案: 使用Mockito,您可以像这样 监视真实对象 : 有一些陷阱,因此也请查看相关文档。

  • 实际上,它的测试如果eat方法对宠物有效,但我也需要检查feedPet方法对玩家也有效。 任何想法或建议都非常感谢。

  • 我想使用regex来查看是否存在某个集合以外的任何字符。 “pvc”返回False 'pd'返回True 'p('返回True 我如何用RE来表达这个?谢了。

  • 我确信这是一个很常见的问题,但我真的无法摆脱这个问题,我正在嘲弄私有方法,它内部调用另一个方法并返回一个集合。类有一个公共方法,它调用私有方法来获取集合对象。我使用PowerMock创建了一个私密方法的间谍。 测试类-: 因此,为了测试公共方法“method1”,我使用PowerMockito创建了一个spy来监视私有方法并返回一个演示列表。 上面调用private method,然后尝试调用Wr

  • 问题内容: 我正在使用 Junit 通过 Seleniun WebDriver 运行测试。我试图将测试分成功能区域,以更好地报告错误。我创建了测试以测试页面加载/将文档移动到其他工作流程。如果页面加载测试失败,或者工作流移动失败,我想跳过后续的页面/工作流测试。 如果测试A失败,如何跳过班级中的其余测试或在班级B中运行测试? 注意: 我意识到我要问的是“ UNIT TESTS的 不良实践* 。但是