unit-testing - 在这种情况下如何使用模拟?

标签 unit-testing mocking

这是我的问题:

这是我尝试编写测试用例的方法。

此方法尝试创建“HttpClient”实例,但此服务器在我这边不可用。

所以我试图通过使用模拟来实现这一点,但我没有成功。

那么有人可以告诉我该怎么做吗?

方法如下:

  public boolean callGet(final boolean keepResult) {
            boolean ok = false;
            if (url != null) {
                try {
                    log.appendLine("Url:");
                    log.append(url);
                    final HttpClient client = new HttpClient();
                    setAuthentication(client);
                    final GetMethod method = new GetMethod(url);
                    if (Utils.isFilled(userAgent)) {
                        method.setRequestHeader("User-Agent", userAgent);

                    }
                    status = client.executeMethod(method);
                    ok = (status == HttpStatus.SC_OK);
                    log.appendLine("Status http call:");
                    log.append(status);
                    if (ok) {
                        if (keepResult) {
                            if (maxSizeResult > 0) {
                                result = method
                                        .getResponseBodyAsString(maxSizeResult);

                            } else {
                                result = method.getResponseBodyAsString();

                            }
                        }
                    }
                } catch (final Exception e) {
                }
            }
            return ok;

这是我的单元测试方法:

   @Before
        public void start() {
            urlcaller = new UrlCaller();
            UrlCaller mock1 = Mockito.mock(UrlCaller.class);
            Mockito.when(mock1.callGet(true)).thenReturn(true);

        }

        @Test
        public void testSetUserAgent() throws HttpException, IOException {

        boolean t1 = urlcaller.callGet(true);

        System.out.println(t1);

    }

}

这是我收到的错误:

Problem:
    UrlCaller.java
    javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
        ...
        at de.bcode.utilsWithLog.UrlCaller.callGet(UrlCaller.java:115)
        at de.bcode.utilsWithLog.TestUrlCaller.testSetUserAgent(TestUrlCaller.java:52)
    Caused by:
        java.io.EOFException: SSL peer shut down incorrectly
            at sun.security.ssl.InputRecord.read(InputRecord.java:482)
            ...
            at de.bcode.utilsWithLog.UrlCaller.callGet(UrlCaller.java:115)
            at de.bcode.utilsWithLog.TestUrlCaller.testSetUserAgent(TestUrlCaller.java:52)
false

感谢您阅读所有问题:-)希望它足够清楚。

最佳答案

您当前的方法存在几个问题:

在单独测试另一个类时,您通常会使用模拟/ stub /假货/任何东西,即提供协作者类的假实现。 例如,您可以单独对某个 Controller 进行单元测试,并为其每个协作对象提供模拟(一个假存储库、一个假 UrlCaller,...)。这样您就可以单独测试被测系统(= Controller )的实际生产代码,而无需依赖其协作者的正确功能。

您的测试创建了 UrlCaller 类的真实和虚假对象,然后它继续执行真实的 urlcaller 对象。这意味着所有实际的生产代码都会被触发,并且创建的模拟 URL 调用者很高兴什么也不做。

在这些情况下我通常会做的是:

  • 弄清楚 UrlCaller 类的单一职责
  • 如果它有任何难以测试/外部的依赖关系(比如真正的 HTTP 流量),请将它们分离到一个新类中,并提供某种方法用假的替换这个协作对象(您可以通过使用构造函数注入(inject)或子类来做到这一点)例如,测试模式)
  • 在生产代码中为您的协作者提供生产实现
  • 在您的测试代码中提供一个虚假的实现来测试您的被测系统,而无需那些令人讨厌的外部依赖项。

对于您的具体情况:似乎使此代码难以测试的外部依赖项是 HttpClient。尝试从 UrlCaller 中提取对该类的依赖关系。如果这对您来说似乎是一个没有实际意义的问题(“但是 UrlCaller 类不会做任何事情”),我会放弃单独测试 UrlCaller 类的冲动,而只依赖于进行真正的 http 调用的集成测试.

关于unit-testing - 在这种情况下如何使用模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29935136/

相关文章:

unit-testing - 为什么在 goroutine 中声明时 benbjohnson/clock 模拟计时器不执行?

c# - 在 C# 中,如何对客户端用户交互和 javascript (jQuery) 代码进行单元测试?

java - 递归的性能

java - 对象内部方法的模拟创建

c++ - 如何使用 google test/mock 测试基于 MFC CWnd 的类?

unit-testing - 如何使 Mock 对象与目标对象保持同步

testing - Spock 测试框架中 Mock/Stub/Spy 的区别

java - 使用 java 1.4 进行模拟

android - UnitTest 中 MutableLiveData 的 setValue 和 postValue

c++ - 如何在 2012 年在 Linux 上设置 googletest?