【问题标题】:need help to unit test my service layer in my mvc3 project需要帮助在我的 mvc3 项目中对我的服务层进行单元测试
【发布时间】:2012-07-16 20:00:31
【问题描述】:

我的 mvc3 项目有服务层和存储库层。

我的服务层:

public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;

    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public ActionConfirmation<User> AddUser(User user)
    {
        User existUser = _userRepository.GetUserByEmail(user.Email, AccountType.Smoothie);
        ActionConfirmation<User> confirmation;

        if (existUser != null)
        {
            confirmation = new ActionConfirmation<User>()
                               {
                                    WasSuccessful = false,
                                    Message = "This Email already exists",
                                    Value = null
                               };

        }
        else
        {
            int userId = _userRepository.Save(user);
            user.Id = userId;

            confirmation = new ActionConfirmation<User>()
                               {
                                   WasSuccessful = true,
                                   Message = "",
                                   Value = user
                               };
        }

        return confirmation;


    }

}

这是我的单元测试,不知道如何执行和断言。请帮帮我,如果您需要其他层的代码,请告诉我。我会把它们放在这里。我认为这应该足够了。

[TestFixture]
public class UserServiceTests
{
    private UserService _userService;
    private List<User> _users;
    private Mock<IUserRepository> _mockUserRepository;

    [SetUp]
    public void SetUp()
    {
        _mockUserRepository = new Mock<IUserRepository>();
        _users = new List<User>
                     {
                        new User { Id = 1, Email = "test@hotmail.com", Password = "" },
                        new User { Id = 1, Email = "test2@hotmail.com", Password = "123456".Hash() },
                        new User { Id = 2, Email = "9422722@twitter.com", Password = "" },
                        new User { Id = 3, Email = "john.test@test.com", Password = "12345".Hash() }
                     };
    }

    [Test]
    public void AddUser_adding_a_nonexist_user_should_return_success_confirmation()
    {
        // Arrange
        _mockUserRepository.Setup(s => s.Save(It.IsAny<User>())).Callback((User user) => _users.Add(user));
        var newUser = new User { Id = 4, Email = "newuser@test.com", Password = "1234567".Hash() };

        _userService = new UserService(_mockUserRepository.Object);


        // Act


        // Assert

    }

}

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 unit-testing nunit


    【解决方案1】:

    我将首先根据用户是否已经存在来测试返回的确认对象。您要验证的另一件事是当用户不存在时调用_userRepository.Save

    【讨论】:

      【解决方案2】:
      // Act
      var result = _userService.AddUser(newUser);
      // Assert
      Assert.IsTrue( /* Insert some condition about the result */ );
      Assert.IsTrue( /* Rinse, wash, repeat */ );
      

      【讨论】:

      • >>/* 冲洗,洗涤,重复 */
      【解决方案3】:

      顺便说一句,最好在编写代码之前编写测试。这将允许您设计更方便的 API,并且您在编写测试时不会受到实现细节的限制。

      回到你的情况。您正在使用模拟存储库,因此您不需要调用Save 来用一些用户填充存储库。实际上,您根本不需要填充模拟。您应该只返回测试场景所需的值。

      [Test]
      public void ShouldSuccesfulltyAddNonExistingUser()
      {
         // Arrrange
         int userId = 5;
         var user = new User { Email = "newuser@test.com", Password = "1234567".Hash() };
         _mockUserRepository.Setup(r => r.GetUserByEmail(user.Email, AccountType.Smoothie)).Returns(null);
         _mockUserRepository.Setup(r => r.Save(user)).Returns(userId);
         _userService = new UserService(_mockUserRepository.Object);
      
         // Act
         ActionConfirmation<User> confirmation = _userService.AddUser(user);
      
         // Assert       
         Assert.True(confirmation.WasSuccessful);
         Assert.That(confirmation.Message, Is.EqualTo(""));
         Assert.That(confirmation.Value, Is.EqualTo(user));
         Assert.That(confirmation.Value.Id, Is.EqualTo(userId));
      }
      

      请记住,在创建新用户时,您不应提供用户 ID。应在用户保存到存储库后分配 ID。

      【讨论】:

      • 非常感谢,这正是我需要的。您能详细说明一下吗(顺便说一句,最好在编写代码之前编写测试。)?代码你的意思是服务层的实现应该在测试之后写?
      • @feelexit 完全正确。您从测试不存在的代码开始。因此,您专注于代码应该做什么,而不是如何。这种方法允许您创建简单易用的 API。编写测试后,您可以通过添加所需的方法(例如添加 UserService.AddUserIUserRepository.GetUserByEmailIUserRepository.Save 的定义)使编译器满意。然后你编写最简单的愚蠢实现让你的测试通过,然后你通过重构让你的代码大放异彩。
      猜你喜欢
      • 2017-05-28
      • 1970-01-01
      • 2012-05-12
      • 2011-08-12
      • 2016-12-14
      • 1970-01-01
      • 2010-12-05
      • 2019-09-17
      • 2021-01-06
      相关资源
      最近更新 更多