使用noparameters分支的void方法的测试用例

时间:2016-06-29 02:48:44

标签: java junit

我有没有参数的String方法,但它有if条件。

public String id1()
{
    Random random=new Random();
    int i=random.nextInt();
    if(i<0)
    {
        i=-(i);
    }
    if(i<1000)
        i=i+1000;
    while(i>9999)
    {
        i=i/10;
    }
    return i+"";
}

如何在这种情况下编写一个Junit测试用例?

3 个答案:

答案 0 :(得分:3)

您可以将逻辑分解为自己的方法:

public String id1(int i)
{
    if(i<0)
    {
        i=-(i);
    }
    if(i<1000)
        i=i+1000;
    while(i>9999)
    {
        i=i/10;
    }
    return i+"";
}

然后通过传递一个随机的int:

来改变你调用id1的方式
id1(new Random().nextInt());

然后你可以测试逻辑。这是最简单的解决方案,即使不是最完美的解决方案。更难的解决方案是模拟nextInt()方法,以便控制它在测试中返回的内容 - 这里可能没有必要,但对于某些情况来说这是唯一的方法。

答案 1 :(得分:2)

像这样的东西。你的考试班:

import java.util.Random;

public class Simple {
    public String id1()
    {
        Random random=new Random();
        int i=random.nextInt();
        if(i<0)
        {
            i=-(i);
        }
        if(i<1000)
            i=i+1000;
        while(i>9999)
        {
            i=i/10;
        }
        return i+"";
    }
}

测试(我使用powermock-mockito-1.6.2)。您应该操纵生成的数字:

import java.util.Random;

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

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Random.class, Simple.class })
public class SimpleTest {

    @Test
    public void ifGenerateNumberLessZeroSetItMoreThanZero() throws Exception {
        Random rand = Mockito.mock(Random.class);
        PowerMockito.mockStatic(Random.class);
        PowerMockito.whenNew(Random.class).withNoArguments().thenReturn(rand);

        Mockito.when(rand.nextInt()).thenReturn(-9999);

        Simple simple = new Simple();
        Assert.assertEquals("9999", simple.id1());
    }
}

答案 2 :(得分:0)

您的问题是您创建了不可测试的代码。

关键是:如果一个方法创建输入它正在自行工作......那么根本没有测试该方法。是的,您可以使用PowerMock来控制随机类,但这是完全错误的方法。 PowerMock只是 nobody 应该使用的东西(由于某些原因,请参阅here);如果有的话,你将它用于你无法改变的第三方代码。但是当我们谈论你自己的代码时,那么提出可测试的设计要好得多;而不是创建一个糟糕的设计,然后转向PowerMock以某种方式测试它。

一般情况下,您使用依赖注入来控制&#34;数据&#34;你的方法将与谁合作;在这种情况下,这可能很简单:

public String formatStringIdFrom(int id) { ... }

如果您真的想提高代码质量,我建议您退一步约5个小时,观看来自Google技术series的所有视频...相信我,绝对是值得你花时间。

其他一些说明:

  • 良好的单元测试的本质是......它们总是返回相同的结果。这意味着:基于随机值的代码...至少应该允许提供种子,以便您可以编写保证始终看到相同的测试用例输入。在每次运行中给出不同结果的单元测试......简单地说:不是很有帮助。
  • id1()对于方法来说是一个非常无用的名称。它没有告诉你任何关于应该采用什么方法
  • 考虑创建一个真正代表ID的具体类。好的设计是关于创建抽象,让您以更有意义的方式处理事情。只是推动整数;并声明由这样的整数构成的任何4位数字符串都是&#34; id&#34; ......简直是一种非常天真的做法。
  • 最后:您可以大大简化4位数的生成;你只需要:int number = random.nextInt(9000) + 1000直接给你(1000,9999)之间的值。