利用方法内部的静态调用设计Java单元测试

利用方法内部的静态调用设计Java单元测试,java,spring,unit-testing,mockito,testng,Java,Spring,Unit Testing,Mockito,Testng,我试图为一个类创建一个单元测试,该类的方法使用apache的fluent hc库()中的Request.Post方法 问题是,我不希望每次运行测试套件时它都发送一个实际的请求,如果它是一个单元测试,而不是一个集成测试,就更不用说了。但我不知道该怎么解决这个问题 我是测试界的新手,在我读到的大部分时间里,当你不能测试某些东西时,类的设计有问题 public class HttpRequestSenderServiceImpl implements RequestSenderService { @

我试图为一个类创建一个单元测试,该类的方法使用apache的fluent hc库()中的Request.Post方法

问题是,我不希望每次运行测试套件时它都发送一个实际的请求,如果它是一个单元测试,而不是一个集成测试,就更不用说了。但我不知道该怎么解决这个问题

我是测试界的新手,在我读到的大部分时间里,当你不能测试某些东西时,类的设计有问题

public class HttpRequestSenderServiceImpl implements RequestSenderService {

@Override
public Response sendRequest(String address, String messageBody) throws IOException {
    Request request = Request.Post(address).bodyString(messageBody, ContentType.APPLICATION_JSON);
    Response response = request.execute();

    return response;
}
}

我使用Spring框架和Spring测试、Mockito和TestNG作为测试工具。如果你能给我指出正确的方向,任何可以阅读的材料,书籍,视频,任何东西,我都会非常感激。我只是想学着用正确的方式去做


我已经找到了一些解决我问题的“解决方案”,但它们都使用了PowerMockito,因为我所读到的内容对您不利,因为它允许模拟静态方法、构造函数等,这会转化为糟糕的编码实践,这正是我在这里试图避免的。

对于您来说,问题更多地出现在apache流畅的hc
请求中。Post
,这是静态的,与您的代码相比,不是模拟友好的

您可以使用和mock execute方法,或者如果您想使用
Request.Post
将其包装到另一个低级服务接口中并使用它:

interface RequestSender {
      Response send(String addr,msgBody)
}

class RequestSenderImpl implements RequestSender {
    public Response send(String addr,msgBody) {
       Request request = Request.Post(address).bodyString(messageBody,ContentType.APPLICATION_JSON);
       Response response = request.execute();
       return response;
    }
}

这样,即使没有mockito,您也可以轻松地模拟代码。

出于您的目的,问题更多地出现在apache的fluent hc
请求中。Post
,它是静态的,不支持模拟,而不是您的代码中

您可以使用和mock execute方法,或者如果您想使用
Request.Post
将其包装到另一个低级服务接口中并使用它:

interface RequestSender {
      Response send(String addr,msgBody)
}

class RequestSenderImpl implements RequestSender {
    public Response send(String addr,msgBody) {
       Request request = Request.Post(address).bodyString(messageBody,ContentType.APPLICATION_JSON);
       Response response = request.execute();
       return response;
    }
}
这样,即使不使用mockito,您也可以轻松地模拟代码。

为上述问题提供了一个建议,我认为这是一种方法

然而,对于前面提到的使用模拟框架,我不认为这一直都是一种完全不好的做法。考虑这个建议,您可能最终会使用一个单元测试请求ReestEnrimIML及其业务逻辑。

但是会有一个类,比如-
FluentCrequestSender
,负责实际调用
Request.Post
。现在,如果要为所有类编写UTs,则必须使用mocking框架测试
FluentCrequestSender
,以确保该类使用正确的API

有一个地方可以使用模拟框架进行测试。但一般来说,如果您的依赖项是您、您的团队或您的组织创建的类,那么如果您最终使用模拟框架,那么它只会指向一个糟糕的设计

为了回答您的问题,可以帮助您更好地编写UT和代码

-这可能是一件总是在后面的事情 当我写代码的时候,我脑子里的想法

这对我有好处

-在我的练习中,不太容易 严格遵守你的日常生活,但这至少迫使我 不要推迟我的UTs,并与我的实际工作同时进行 课程(如果不是之前)

-抓住一本好的设计模式书/视频 如果您可以访问或购买图书馆。这些概念似乎 令人畏惧,但我发现其中一些在我的日常生活中真的很有用 工作,尤其是在写UTs的时候

但就个人而言,最好的学习方法是在代码库中查看现有代码,并查看哪些代码好,哪些代码可以改进。我发现,那些设计优秀的人编写的代码比任何一本书都有用

希望这根长长的发条对你有帮助

PS-努力以正确的方式做事的荣誉。虽然应该经常说,但有时并不经常说

为上述问题提供了一个建议,我认为这是解决问题的一种方法

然而,对于前面提到的使用模拟框架,我不认为这一直都是一种完全不好的做法。考虑这个建议,您可能最终会使用一个单元测试请求ReestEnrimIML及其业务逻辑。

但是会有一个类,比如-
FluentCrequestSender
,负责实际调用
Request.Post
。现在,如果要为所有类编写UTs,则必须使用mocking框架测试
FluentCrequestSender
,以确保该类使用正确的API

有一个地方可以使用模拟框架进行测试。但一般来说,如果您的依赖项是您、您的团队或您的组织创建的类,那么如果您最终使用模拟框架,那么它只会指向一个糟糕的设计

为了回答您的问题,可以帮助您更好地编写UT和代码

-这可能是一件总是在后面的事情 当我写代码的时候,我脑子里的想法

这对我有好处

-在我的练习中,不太容易 严格遵守你的日常生活,但这至少迫使我 不要推迟我的UTs,并与我的实际工作同时进行 课程(如果不是之前)

-抓住一本好的设计模式书/视频 如果您可以访问或购买图书馆。这些概念似乎 令人畏惧,但我发现其中一些在我的日常生活中真的很有用 工作,尤其是在写UTs的时候

但就个人而言,最好的学习方法是在代码库中查看现有代码,并查看哪些代码好,哪些代码可以改进。我发现,那些设计优秀的人编写的代码比任何一本书都有用

希望这根长长的发条对你有帮助


PS-努力以正确的方式做事的荣誉。虽然应该经常说,但有时并不经常说

所以你想模拟一个静态方法,对吗?不完全是,我想知道的是,我怎么能以一种我不需要的方式设计那个类