【问题标题】:Unit testing method which is using a private field initialized with static method使用静态方法初始化的私有字段的单元测试方法
【发布时间】:2020-11-14 16:20:49
【问题描述】:

在我的班级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()twitchCliendBuilder.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");
        }

    }
}

但是我在twitchClient 上得到NullPointerExceptionsendChatMessage() 任何想法如何正确模拟这样的字段?

【问题讨论】:

  • 你到底想测试什么?

标签: java unit-testing testing junit mockito


【解决方案1】:

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(...);
        ...
    }

在真实代码中,我们“注入”由TwitchClientBuilder构建的真实TwitchClient

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-27
    • 2012-07-22
    • 2023-04-01
    • 2012-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多