当您在嘲笑框架中嘲笑一个类时,您是否手动站立实际的嘲讽类?

时间:2018-12-14 16:34:05

标签: java unit-testing mockito

我对Mockito框架还很陌生。我一直在阅读有关它的多个教程。我关注的对象之一是:https://www.tutorialspoint.com/mockito/mockito_first_application.htm

有一条声明创建了Stock Service的模拟。

In this example, we've created a mock of Stock Service to get the dummy price of some stocks

我的问题是Stock Servicea real service class还是mock service class,您必须手动站起来模仿真实的服务类。我有点困惑。对junit框架有基本的了解。我以前练习过的是,如果有一个服务类Foo,那么我使用的是提供所有公开方法的实际类。

public class Foo {

    public Foo() { } // construtor

    public String returnAddress(String userId) {
        // ...
        return dataAccesobj.getAddress(userId);
    }
}

如果我没记错的话,请在单元测试中致电foo.returnAddress(..)

我问这个问题的原因是,当我与mockito合作为一个类创建测试方法时,遇到了一个独特的挑战?

我从一个真实的服务类开始,该类依赖于其超类构造函数来返回其实例。我遇到的挑战是,这个超类构造函数启动了数据库连接以及加载/解析我不需要测试的属性文件。我在考虑如何防止数据库连接和加载/读取属性文件。...

我认为我从mockito一本教程中读到,您可以在没有此类服务的情况下隔离测试。我尝试使用@Mock@Spy(对它们的用途还不是很了解。),但对输出没有任何影响(也许我误用了这些注释)。

因此,我所做的实际上是通过简单地将其复制并重命名为Foo并将其放置在FooMock文件夹中而在真实服务类(例如src/test/java)之外创建伪造/模拟类。在其中运行单元测试类的位置。除了保留db connectionloading/reading prop file for env specific之类不需要的逻辑之外,我使模拟类与真实服务类完全相同。通过这样做,我能够测试一种读取ldap目录的公开方法...

对不起,我感到困惑,但是希望我的观点在这一点上是明确的。我不确定我处理这种情况的方式是对还是错。非常感谢经验丰富的工程师以mockito的方式阐明我接受此问题的方式是否可以接受。如果没有,那么请给我最好的处理方法。

1 个答案:

答案 0 :(得分:0)

有了Mockito, 模拟是包装器类的实现。 模拟对象“包装”模拟对象 (您的示例中的服务) 并允许您定义每种方法的功能。

Mockito有两个模拟功能选项; 调用包装方法,不要调用包装方法。

我不知道何时调用包装方法, 所以我总是使用不调用包装方法。

创建模拟后, 使用Mockito.doReturn(returnvalue).when(mockObject).method(method parameters)方法来模拟功能。

编辑:更多信息。

我将假定您正在使用junit v4。 具体细节将根据junit主要发行版号而有所不同, 但实际工作将是相同的。

  1. 使用注释定义您的Mock对象(@Mock), 除了一些特殊情况。 这将创建非最终类的模拟, 抽象类 和界面。
  2. 使用@Before批注创建“测试前”方法; 我通常将此方法命名为preTestSetup, 但实际名称没有关系。
  3. 调用MockitoAnnotations.initMocks(this)作为第一行代码 在“测试前”方法中。 这将找到@Mock注释,并为每个注释实例化一个模拟。
  4. 使用ReflectionTestUtils.setField方法将模拟注入到您的对象中(假设您没有设置方法, 传统上我不喜欢)。
  5. 使用Mockito.doReturn(returnvalue).when(mockObject).method(method parameters)技术定义每种方法的模拟功能。

这是一些示例代码 (警告: 这应该是功能齐全的 但我没有编译):

public interface MyService
{
    String blammy(SomeParameter parameter);
}

public class UsesMyService
{
    @Autowired
    private MyService myService;

    public String kapow(final SomeParameter parameter)
    {
        return myService.blammy(parameter);
    }
}

public class UnitTestUsesMyService
{
    private UsesMyService classToTest;

    @Mock
    private MyService mockMyService;

    @Mock
    private SomeParameter mockSomeParameter;

    @Before
    public void preTestSetup()
    {
        MockitoAnnotations.initMocks(this);

        classToTest = new UsesMyService();

        doReturn("Blam").when(mockMyService).blammy(mockSomeParameter);

        ReflectionTestUtils.setField(
            classToTest,
            "myService",
            mockMyService);
    }

    @Test
    public void kapow_allGood_success()
    {
        final String actualResult;


        actualResult = classToTest.kapow(mockSomeParameter);


        assertNotNull(actualResult); // Not strictly necessary.

        assertEquals(
            "Blam",
            actualResult);
    }
}