如何为该方法创建单元测试?

时间:2019-06-05 10:59:49

标签: java unit-testing testing junit

如何为该服务创建单元测试:

public class UserService {

    private Map<String, User> userStorage = new HashMap<>();

    public void saveOrUpdate(User user) {
        User userFromStorage = userStorage.get(user.getId());

        if (userFromStorage == null) {
            userStorage.put(user.getId(), user);
        } else {
            userFromStorage.setName(user.getName());
            userStorage.put(userFromStorage.getId(), userFromStorage);
        }
    }
}

如何检查用户创建或更新成功?

我可以将void更改为User并返回更新的用户并创建它:

assertEquals(user.getName(), updatedUser.getName())

但是如果我不能更改方法签名怎么办?我该如何测试?

2 个答案:

答案 0 :(得分:2)

您同时嘲笑userStorage和传递的User

@RunWith(MockitoJunitRunner.class)
class UserServiceTest {
    @InjectMocks private UserService sut;
    @Mock private Map<String, User> storage;
    @Test
    public void testUpdate() {
        final String ID = "1";
        // setup user passed to method
        User user = mock(User.class);
        when(user.getId()).thenReturn(ID);
        when(user.getName()).thenReturn("name");
        // setup user already known to service
        User fromStorage = mock(User.class);
        when(fromStorage.getId()).thenReturn(ID);
        when(storage.get(ID)).thenReturn(fromStorage);

        // run method under test
        sut.saveOrUpdate(user);

        // check update was performed and storage updated
        verify(fromStorage).setName("name");
        verify(storage).put(ID, fromStorage);
    }
}

我将把save的路径留给您;其实更简单。

答案 1 :(得分:0)

我不会在这里嘲笑任何东西。

您有一个HashMap和一个User。为了能够与他们合作,它们都需要公开访问。

我不是Java开发人员,所以我会将编码方面留给其他人。

我首先将UserStorage注入到类中(例如在构造函数中),以便可以使用它,甚至可以更改实现。例如,使用一个接口,以便在需要时可以有多种实现。

一旦这样做,就可以使用它从服务中检索用户,并且可以对其进行断言。

测试1:添加

  • 初始化空存储
  • 创建ID = 1,名称= Peter的用户
  • 与此用户通话saveOrUpdate
  • 从存储中检索ID = 1的用户
  • 确认它等于您输入的用户。

测试2:更新

  • 初始化空存储
  • 创建ID = 1,名称= Peter的用户
  • 与此用户通话saveOrUpdate
  • 将用户名更新为John
  • 使用更新的用户呼叫saveOrUpdate
  • 从存储中检索ID = 1的用户
  • 断言它等于更新的用户

为空用户或您要测试的任何其他条件添加更多测试。 我不会嘲笑这个,而是测试真实的东西。

这不涉及更改方法的签名,仅涉及将存储注入IOC框架中的类的方式,如果您使用一个或简单的DI,则根本没有太大的改变。