使用存根也作为模拟

时间:2014-09-17 13:31:28

标签: c# unit-testing xunit.net

我有一个班级说ChatService,我有一个名为JoinRoom()的方法返回void。此方法将用户及其连接详细信息作为参数,并将用户与其连接详细信息一起保存到数据库中,或者如果用户已存在于数据库中,则会在数据库中添加用户的连接详细信息,然后根据任何一个条件提出一个事件。我想测试一下这个方法:

  1. 保存新用户及其连接详情(适用于新用户)
  2. 保存现有用户的连接详细信息。
  3. 当上述任一操作成功时,引发事件。
  4. 我已经通过测试检查用户及其连接是否正确保存,还检查事件是否正确引发。例如:

        [Fact]
        public void user_should_be_created_and_added_to_the_room_if_user_does_not_exist()
        {
            chatService.JoinRoom(validConnectionId, validRoom, validUsername);
    
            Assert.False(userExist);
            Assert.True(repository.AddUserCalled);
        }
    
        [Fact]
        public void then_connection_should_be_added_for_an_existing_user()
        {
            repository.AddUser(new User(validUsername, userpix));
            repository.AddUserCalled = false;
    
            chatService.JoinRoom(validConnectionId, validRoom, validUsername, userpix);
    
            Assert.False(repository.AddUserCalled);
            Assert.True(repository.ConnectionAdded);
            Assert.Equal(1, repository.NoOfConnectionAdded);
        }
    

    我已经进行了单独的测试,检查事件是否被正确引发,但我担心的是在我的假存储库上断言是正确的,或者,如果存储库充当存根,那么我应该断言如果事件被提出来了。似乎测试关注的是被测方法的内部结构,如果它是正确的,我不会这样做。

1 个答案:

答案 0 :(得分:0)

你的问题缺乏如何消耗JoinRoom的背景,但很少出现问题:

  • 为什么JoinRoom 创建用户?用户创建与加入会议室有什么关系?在您加入会议室之前,您是不是应该已经成为某种类型的用户(新用户可能会匿名加入 )?我会重温这个功能。
  • connectionId和userName都听起来像连接用户的标识属性;当上面的用户创建问题得到解决时(您不应同时需要两者),可以解决这个问题。
  • 您使用(看起来像是什么)手动模拟而不是生成库的任何原因(MoqFakeItEasy)?

在当前状态下,您的测试似乎没问题(在单次测试中使用组件作为存根和模拟并不常见)。考虑到上述要点,我会将JoinRoom更改为:

void JoinRoom(Room room, UserConnectionInfo userConnectionInfo)

或者(这需要在内部的某处提取连接):

void JoinRoom(Room room, User user)