Java 使用静态方法初始化的私有字段的单元测试方法

Java 使用静态方法初始化的私有字段的单元测试方法,java,unit-testing,testing,junit,mockito,Java,Unit Testing,Testing,Junit,Mockito,在我的类TwitchService中,我正在使用TwitchClientBuilder创建一个私有字段twitchClient。如何接近使用twitchClient的测试方法sendChatMessage() public class TwitchService { public TwitchService(){ twitchClient = TwitchClientBuilder.builder().build(); } public void se

在我的类
TwitchService
中,我正在使用
TwitchClientBuilder
创建一个私有字段
twitchClient
。如何接近使用twitchClient的测试方法
sendChatMessage()

public class TwitchService {

    public TwitchService(){
        twitchClient = TwitchClientBuilder.builder().build();
    }

    public void sendChatMessage(String content) throws Exception {
        if(content.isEmpty()){
            throw new Exception("Cannot send empty message!");
        }

        twitchClient.getChat().sendMessage(content);
    }
}
到目前为止,我已经试着模仿TwitchClientBuilder.builder()和TwitchClientBuilder.build()如下:

@RunWith(MockitoJUnitRunner.class)
public class TwitchServiceTest {

    private TwitchService twitchService;

    @Mock
    private TwitchClientBuilder twitchClientBuilder;


    @Test
    public void sendChatMessage() throws Exception {

        try (MockedStatic<TwitchClientBuilder> twitchClientBuilderMockedStatic = Mockito.mockStatic(TwitchClientBuilder.class)){
            twitchClientBuilderMockedStatic.when(() -> TwitchClientBuilder.builder()).thenReturn(mock(TwitchClientBuilder.class));

            when(twitchClientBuilder.build()).thenReturn(mock(TwitchClient.class));
            twitchService = new TwitchService("x", "y");
            twitchService.sendChatMessage("test message");
        }

    }
}
@RunWith(MockitoJUnitRunner.class)
公共类TwitchService测试{
私人TwitchService TwitchService;
@嘲弄
私人TwitchClientBuilder TwitchClientBuilder;
@试验
public void sendChatMessage()引发异常{
try(MockedStatic twitchClientBuilderMockedStatic=Mockito.mockStatic(TwitchClientBuilder.class)){
TwitchClientBuilderLockedStatic.when(()->TwitchClientBuilder.builder())。然后返回(mock(TwitchClientBuilder.class));
when(twitchClientBuilder.build()).thenReturn(mock(TwitchClient.class));
twitchService=新twitchService(“x”、“y”);
twitchService.sendChatMessage(“测试消息”);
}
}
}
但是我在
sendChatMessage()
您知道如何正确模拟这样的字段吗?

使用TwitchClient的构造函数依赖项注入,而不是通过调用builder对其进行硬编码

只需重新编写服务,如下所示:

public class TwitchService {

    private final TwitchClient twitchClient

    public TwitchService(final TwitchClient twitchClient) {
        this.twitchClient = twitchClient;
    }

...
}
TwitchService
现在与
TwitchClient
的实现松散耦合,这使您能够在单元测试中模拟客户端,并在真实代码中使用真实的实现(由自身进行单元测试)

因此,在单元测试中,我们可以模拟TwitchClient:

@RunWith(MockitoJUnitRunner.class)
public class TwitchServiceTest {

    @Mock
    private TwitchClient mockedTwitchClient;

    // Tested instance
    private TwitchService twitchService;

    @Before
    public void before() {
        twitchService = new TwitchService(mockedTwitchClient);
    }

    @Test
    public void ourTest() {
        when(mockedTwitchClient.xyz()).thenReturn(...);
        ...
    }

在real代码中,我们“注入”real
TwitchClient
TwitchClientBuilder
构建:

...
twitchService = new TwitchService(TwitchClientBuilder.builder().build());
...

你到底想测试什么?