有没有一种方法可以使用模拟对象来赋值给对象?

huangapple go评论91阅读模式
英文:

Is there a way to assign value to object using mocks

问题

Sure, here's the translated content:

我有一个方法,它:

  1. 接受字符串作为参数。
  2. 使用该字符串创建对象。
  3. 将该对象传递给另一个方法。
  4. 然后,第二个方法更改该对象上的属性。
  5. 接着,原始方法检查是否已更改该属性,如果没有更改,则抛出异常。

以下是代码。这个方法不能被修改。

internal sealed class CreateUserCommandHandler
{
    private readonly IUserRepository _userRepository;

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

    public async Task Handle(string firstName)
    {
        var user = new User(firstName);

        await _userRepository.CreateUser(user);

        if (user.Id == null)
            throw new Exception("User Id is null after creation.");
    }
}

我想使用单元测试来测试这个方法。我不知道如何设置用户存储库模拟,以便它会分配id属性。

[Fact]
public async Task GivenCorrectCommand_WhenHandlerIsExecuted_ThenEntityShouldContainId()
{
    // 准备;
    var firstName = "FirstName";
    var commandHandler = new CreateUserCommandHandler(_userRepositoryMock.Object);

    // 执行
    // 这会因为user.Id属性等于null而引发异常
    var result = await commandHandler.Handle(firstName);

    // 断言
    result.Should().NotBeNullOrWhiteSpace();
}

我使用的是.NET 7,xUnit,Moq和FluentAssertions,如果可能的话,我宁愿不引入新的库。

英文:

I have a method that:

  1. Accepts string as a parameter.
  2. Creates object using that string.
  3. Passes that object into another method.
  4. That second method then changes a property on that object.
  5. Then the original method checks if that property was changed, and throws an exception if it wasn't.

Code below. This method cannot be modified.

internal sealed class CreateUserCommandHandler
{
    private readonly IUserRepository _userRepository;

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

    public async Task Handle(string firstName)
    {
        var user = new User(firstName);

        await _userRepository.CreateUser(user);

        if (user.Id == null)
            throw new Exception("User Id is null after creation.");
    }
}

I want to test this method with unit tests. I don't know how to set up a user repository mock so that it would assign id property.

[Fact]
public async Task GivenCorrectCommand_WhenHandlerIsExecuted_ThenEntityShouldContainId()
{
    // Arrange;
    var firstName = "FirstName";
    var commandHandler = new CreateUserCommandHandler(_userRepositoryMock.Object);

    // Act
    // This throws an exception because of the user.Id property is equal to null
    var result = await commandHandler.Handle(firstName);

    // Assert
    result.Should().NotBeNullOrWhiteSpace();
}

I am using .NET 7, xUnit, Moq and FluentAssertions, I would prefer not to introduce new library if possible.

答案1

得分: 1

你可以在userRepositoryMock中加入一些逻辑,就像这样:

_userRepositoryMock
  .Setup(x => x.CreateUser(It.IsAny<User>()))
  .Callback((User u) => u.Id = 123);
英文:

You can put some logic into userRepositoryMock like this

_userRepositoryMock
  .Setup(x =&gt; x.CreateUser(It.IsAny&lt;User&gt;()))
  .Callback((User u) =&gt; u.Id = 123);

huangapple
  • 本文由 发表于 2023年4月13日 22:24:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006583.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定