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

Unit testing 在这种情况下如何使用模拟?,unit-testing,mocking,Unit Testing,Mocking,我的问题是: 这就是我试图编写测试用例的方法 此方法试图创建“HttpClient”的实例,但此服务器在我这边不可用 所以我试图通过模仿来实现这一点,但我没有成功 有人能告诉我怎么做吗 方法如下: public boolean callGet(final boolean keepResult) { boolean ok = false; if (url != null) { try {

我的问题是:

这就是我试图编写测试用例的方法

此方法试图创建“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

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

您当前的方法有几个问题:

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

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

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

  • 找出UrlCaller类的单一职责
  • 如果它有任何难以测试的/外部依赖项(如真实的HTTP流量),请将这些依赖项分离到一个新类中,并提供某种方法用伪对象替换此协作对象(例如,您可以使用构造函数注入或子类来测试模式)
  • 在生产代码中为合作者提供生产实现
  • 在测试代码中提供一个伪实现,以便在没有这些讨厌的外部依赖的情况下测试被测系统

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

您的测试没有多大意义。您创建一个mock并在测试中调用该mock

通常你是这样做的:

  • 创建一个模拟(最好是一个接口)
  • 将模拟注入被测单元
  • 给你的测试单元打电话

我认为您应该将要模拟的部分与要测试的代码分开,并通过接口注入模拟的部分。

您要测试哪些代码?