我应该出于什么原因嘲笑? [英] For what reason should I mock?

查看:110
本文介绍了我应该出于什么原因嘲笑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Mockito and PowerMockito as well. I found out that I can not test static methods with pure Mockito so I need to user PowerMockito (right?).

我有一个非常简单的名为Validate的类,它具有这种非常简单的方法

I have very simple class called Validate with this very easy method

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消息参数上调用该静态方法时,将调用IllegalArgumentException
2)当我在null对象参数上调用该静态方法时,将调用IllegalStateException

1) When I call that static method on null message argument, IllegalArgumentException is called
2) When I call that static method on null object argument, IllegalStateException is called

到目前为止,我编写了此测试:

From what I got so far, I wrote this test:

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类,并且正在检查是否以空参数作为对象并以任何字符串作为消息在该方法上调用模拟时,抛出IllegalStateException.

So this says that I mock Validate class and I am checking that when mock is called on that method with null argument as an object and any string as a message, an IllegalStateException is thrown.

现在,我真的不明白.为什么我不能直接调用该方法,而在模拟该静态类时却丢下了整个巫毒术?在我看来,除非我调用Validate.stateNotNull,否则无论如何测试都会通过……我应该出于什么原因对它进行嘲笑?

Now, I really don't get it. Why I just can't call that method directly, dropping the whole voodoo magic around mocking that static class? It seems to me that unless I call Validate.stateNotNull that test passes anyway ... For what reason should I mock it?

推荐答案

首先,确定您的目标是什么,要测试什么. Fortega指出,您的测试不是在测试Validate类方法,而是创建一个行为类似该方法的模拟程序.确定要测试的对象(被测试的对象)以及执行测试所需的对象(协作者),然后查看协作者并确定它们是易于创建的东西还是您需要的东西嘲笑他们.

First, decide what your objective is and what you want to test. Your test isn't testing your Validate class method, it's creating a mock that behaves like that method, as Fortega points out. Identify what it is you are testing (the object under test) and what it is you need in order to perform the test (the collaborators), then look at the collaborators and decide whether they are things that are easy to create or if you need to mock them.

对于此类不依赖任何东西的类,我建议完全不使用模拟.这里没有需要模拟的东西,测试可以这样写:

For something like this class which has no dependencies on anything, I would recommend doing without mocks entirely. There is nothing here that needs mocking, the test can be written like this:

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");
    }
}

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

and that tells you whether the code does what you want it to.

除非存在某种依赖关系,否则不要嘲笑该依赖关系,因为它是外部资源(例如文件系统或数据库)或某些复杂的子系统,因此要避免引入该测试.模拟框架可能非常有用,但是它们增加了复杂性,它们可能过度指定了要测试的事物的行为,使测试变得脆弱,并使测试难以阅读.如果可以的话,请不要使用它们.

Don't mock unless there is some dependency that you want to avoid introducing to the test due to it being either an external resource (like a filesystem or database) or some complex subsystem. The mock frameworks can be very useful but they add complexity, they can over-specify the behavior of the things they are testing, making the tests brittle, and they can make tests hard to read. Do without them if you can.

这篇关于我应该出于什么原因嘲笑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆