如何对测试中的方法中声明的变量的属性进行单元测试

时间:2011-09-23 15:04:08

标签: c# .net tdd nunit moq

我有一个服务层方法,它接收一个对象(Dto)作为参数。

在该方法中,我创建了一个业务对象,并将Dto属性的值传递给业务对象的属性。然后,我将业务对象作为参数传递给存储库方法调用。

我的单元测试如何确保在测试的服务方法中声明的业务对象在其属性中获得正确的值?

2 个答案:

答案 0 :(得分:3)

您可以模拟存储库(我希望您可以将其注入服务层)并检查传递到存储库的业务对象是否具有预期的属性值。

编辑:示例


<强>基础设施:

public interface IRepository
{
   void Add(BusinessObject item);
}

public sealed class ServiceLayerContext
{
   private readonly IRepository repository;

   public ServiceLayerContext(IRepository repository)
   {
       this.repository = repository;
   }

   public void ProcessDto(IDtoObject dto)
   {
       var businessObject = this.CreateBusinessObject(dto);
       this.repository.Add(businessObject);
   }

   private BusinessObject CreateBusinessObject(IDtoObject dto)
   {
   }
}

测试伪代码(因为RhinoMock不是Moq):

   [Test]
   public void ShouldCreateBusinessOBjectWithPropertiesInitializedByDtoValues()
   {
      // ARRANGE
      // - create mock of the IRepository
      // - create dto
      // - setup expectations for the IRepository.Add() method
      //   to check whether all property values are the same like in dto   
      var repositoryMock = MockRepository.GenerateMock<IRepository>();
      var dto = new Dto() { ... };
      BusinessObject actualBusinessObject = null;
      repositoryMock.Expect(x => x.Add(null)).IgnoreArguments().WhenCalled(
        (mi) => 
        {
            actualBusinessObject = mi[0] as BusinessObject;            
        }).Repeat().Any();

      // ACT
      // - create service layer, pass in repository mock
      // - execute svc.ProcessDto(dto)     
      var serviceLayerContext = new ServiceLayerContext(repositoryMock);
      serviceLayerContext.ProcessDto(dto);

      // ASSERT
      // - check whether expectations are passed
      Assert.IsNotNull(actualBusinessObject);
      Assert.AreEqual(dto.Id, actualBusinessObject.Id);
      ...
   }

答案 1 :(得分:0)

非常感谢你的帮助。 下面的示例代码使用moq及其在vb.net中为其他可能遇到类似挑战的vb.net程序员编写。

具体类

Public Class UserService
Implements IUserService

Private ReadOnly userRepository As IUserRepository

Public Sub New( _
   ByVal userRepository As IUserRepository)

    Me.userRepository = userRepository

End Sub

Public Sub Edit(userDto As Dtos.UserDto) Implements Core.Interfaces.Services.IUserService.Edit

    Try
        ValidateUserProperties(userDto)

        Dim user = CreateUserObject(userDto)

        userRepository.Edit(user)


    Catch ex As Exception
        Throw
    End Try

End Sub

Private Function CreateUserObject(userDto As Dtos.UserDto) As User Implements  Core.Interfaces.Services.IUserService.CreateUserObject
    Dim user = New User With {.Id = userDto.Id, _
              .UserName = userDto.UserName, _
              .UserPassword = userDto.UserPassword, _
              .Profile = New Profile With {.Id = userDto.ProfileId}}
    Return user
End Function
Sub ValidateUserProperties(userDto As Dtos.UserDto)



End Sub

测试类

<TestFixture()>
Public Class UserServiceTest

Private userRepository As Mock(Of IUserRepository)
Public serviceUnderTest As IUserService

<SetUp()>
Public Sub SetUp()

    userRepository = New Mock(Of IUserRepository)(MockBehavior.Strict)

    serviceUnderTest = New UserService(userRepository.Object)


End Sub

<Test()>
Public Sub Test_Edit()
    'Arrange
    Dim userDto As New UserDto With {.UserName = "gbrown", .UserPassword = "power", .Id = 98, .ProfileId = 1}

    Dim userObject As User = Nothing

    userRepository.Setup(Sub(x) x.Edit(It.IsAny(Of User))) _
    .Callback(Of User)(Sub(m) userObject = m)

    'Act

    serviceUnderTest.Edit(userDto)


    'Assert

    userRepository.Verify(Sub(x) x.Edit(It.IsAny(Of User)), Times.AtLeastOnce())

    Assert.NotNull(userObject)
    Assert.AreEqual(userDto.Id, userObject.Id)
    Assert.AreEqual(userDto.ProfileId, userObject.Profile.Id)
    Assert.AreEqual(userDto.UserName, userObject.UserName)
    Assert.AreEqual(userDto.UserPassword, userObject.UserPassword)
End Sub
End Class