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

我为什么要嘲笑?

白光耀
2023-03-14

我也是Mockito和PowerMockito的新手。我发现我无法使用纯Mockito测试静态方法,因此我需要使用PowerMockito(对吗?)。

我有一个非常简单的类,名为Validate,使用这个非常简单的方法

public class Validate {
        public final static void stateNotNull(
            final Object object,
            final String message) {
    if (message == null) {
        throw new IllegalArgumentException("Exception message is a null object!");
    }
    if (object == null) {
        throw new IllegalStateException(message);
    }
}

因此,我需要验证:

1) 当我在null message参数上调用该静态方法时,将调用IllegalArgumentException。2)当我在null object参数上调用该静态方法时,将调用IllegalStateException

根据我目前得到的,我写了这个测试:

import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.isNull;

import org.junit.Before;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.testng.annotations.Test;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Validate.class)
public class ValidateTestCase {

    @Test(expectedExceptions = { IllegalStateException.class })
    public void stateNotNullTest() throws Exception {
        PowerMockito.mockStatic(Validate.class);
        Validate mock = PowerMockito.mock(Validate.class);
        PowerMockito.doThrow(new IllegalStateException())
            .when(mock)
            .stateNotNull(isNull(), anyString());
        Validate.stateNotNull(null, null);
    }
}

所以这表示我模拟了Validate类,并且我正在检查当使用null参数作为对象,任何字符串作为消息对该方法调用mock时,是否会引发IllegalStateException。

现在,我真的不明白了。为什么我不能直接调用该方法,放弃了模拟静态类的巫毒魔法?在我看来,除非我调用Validate。stateNotNull测试无论如何都会通过。。。我为什么要嘲笑它?

共有2个答案

宋飞文
2023-03-14

首先,决定你的目标是什么,你想测试什么。正如Fortega指出的那样,测试并不是测试Validate类方法,而是创建一个行为类似于该方法的模拟。确定您正在测试的是什么(被测试的对象)以及执行测试所需的是什么(协作者),然后查看协作者并确定它们是易于创建的还是您需要模拟它们。

对于这样一个对任何东西都没有依赖关系的类,我建议完全不使用mock。这里没有任何东西需要模拟,测试可以这样编写:

import static org.junit.Assert.*;

public class ValidateTestCase {

    @Test
    public void testHappyPath() throws Exception {
        Validate.stateNotNull("", "");
    }

    @Test
    public void testNullMessage() throws Exception {
        try {
            Validate.stateNotNull(null, null);
            fail();
        }
        catch (IllegalStateException e) {
            String expected = "Exception message is a null object!"
            assertEquals(expected, e.getMessage());
        }
    }

    @Test(expected=IllegalStateException.class)
    public void testNullObject() throws Exception {
        Validate.stateNotNull(null, "test");
    }
}

这会告诉您代码是否满足您的要求。

除非由于测试是一个外部资源(如文件系统或数据库)或某个复杂的子系统,您希望避免引入某些依赖项,否则不要进行模拟。模拟框架可能非常有用,但它们会增加复杂性,会过度指定所测试内容的行为,使测试变得脆弱,并且会使测试难以阅读。如果可以的话,不要用它们。

乐健
2023-03-14

您不应该模拟正在测试的类和方法。您应该只模拟执行测试本身所需的方法。

例如,如果您需要Web服务中的一些对象来执行测试,您可以模拟Web服务调用,这样您就不需要实际调用Web服务。

 类似资料:
  • 在groovy中,我试图使用以下方法来模拟请求的返回,但每当代码调用时,我总是得到一个空指针异常: 测试中: 我使用的是Mockito3.12,我的测试只是以空指针异常而失败,我的restTemplate交换(在调试时)返回一个空值。我做错什么了吗? 如果它有助于Rest寺庙交换有以下定义: 对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并以ResponseEntity的形式返回响

  • 问题内容: 请帮忙。将来自扫描仪的提示显示到控制台后,出现此错误: 问题是来自printf吗?我检查了格式,它看起来正确。 这是程序: 问题答案: 答:因为您的格式说明符与方法中使用的输入参数不匹配。 使用而不是将值用作格式说明符 另外需要额外的逃脱角色 最后,删除不必要的点字符 阅读:Formatter javadoc

  • 问题内容: 简介文档中有很多段落专门介绍了和之间的区别,但是实际上,您可以在本地范围内创建对象并将其返回。 为什么要使用一对分配器? 问题答案: 您可以做的事情,您无法做其他任何事情: 建立频道 创建一个预先分配了空间的地图 创建具有预分配空间或len!= cap的切片 证明有一点困难。使它变得更容易的主要事情是创建指向非复合类型的指针。以下两个功能是等效的。简而言之:

  • 我不是流口水的专家。不过,通过实验,我对它有了一些了解。我无法欣赏,为什么我需要它。 我的典型应用程序是业务Web应用程序。是的,他们确实有一些规则。但是,这些都是使用数据库表、SQL查询和中的良好UI来实现的,以便业务用户修改规则。规则不是武断的,它们在投入生产之前是经过仔细考虑的。 我的业务用户永远不会使用(Drools)脚本语言来修改任何内容。更不用说修改规则了。他们非常乐意使用UI屏幕来修

  • 问题内容: Angular应用使用属性而不是事件。 为什么是这样? 问题答案: ng-click包含一个角度表达式。Angular表达式是在Angular 范围的上下文中求值的,该范围绑定到具有ng- click属性的元素或该元素的祖先。 Angular表达式语言不包含流控制语句,也不能声明变量或定义函数。这些限制意味着模板只能访问由控制器或指令提供的变量和运行功能。

  • 我用Spring AOP写了一个非常简单的方面。这是可行的,但我在理解到底发生了什么方面有一些问题。我不明白为什么我必须添加aspectjweaver。罐子Spring AOP文档明确指出,只要我只使用Spring AOP,我就不需要aspectj编译器或weaver: 尽管AOP运行时仍然是纯Spring AOP,并且不依赖AspectJ编译器或weaver。 我的配置如下所示: 我也尝试了XM