我想编写一个测试来确定是否调用了模拟方法

I want to write a test that will definitely tell if the mock-method was called

我有一个方法:

public class CreateNewAccountUseCase
{
    private readonly IAccountRepository _accountRepository;

    public CreateNewAccountUseCase(IAccountRepository accountRepository)
    {
        _accountRepository = accountRepository;
    }

    public virtual async Task Execute(Account account)
    {
       await _accountRepository.Create(account);
    }
}

我在控制器中使用它:

public async Task<ActionResult<AccountModel>>  CreateAccount([FromBody]CreatingAccount creatingAccount)
{
    var account = creatingAccount.ConvertToAccount();

    await _createNewAccountUseCase.Execute(account);

    return Created($"/accounts/{account.Id}", account);
}

我想确保 UseCase 方法将被准确调用。

我写了这个控制器测试:

[Fact]
public async Task Create()
{
    // arrange
    var account = new CreatingAccount();

    var accountRepository = new Mock<IAccountRepository>();
    var createNewAccountUseCase = new Mock<CreateNewAccountUseCase>(accountRepository.Object);

    createNewAccountUseCase.Setup(m => m.Execute(account)).Returns(Task.CompletedTask);

    // act
    await controller.CreateAccount(account);
    // assert
    createNewAccountUseCase.Verify(m => m.Execute(account), Times.Once);
}

我希望 createNewAccountUseCase.Verify() 检查该方法是否是方法,但我得到失败的测试消息:

Moq.MockException : 
Expected invocation on the mock once, but was 0 times: m => m.Execute(account)

Performed invocations:
Mock<CreateNewAccountUseCase:1> (m):
No invocations performed.

如何确保方法 (createNewAccountUseCase.Verify()) 被调用?

你在嘲笑被测对象。而是模拟依赖项并调用测试下的方法

[Fact]
public async Task Create() {
    // arrange
    var account = new CreatingAccount();

    var accountRepository = new Mock<IAccountRepository>();
    accountRepository.Setup(m => m.Create(It.IsAny<Account>())).Returns(Task.CompletedTask);

    var createNewAccountUseCase = new CreateNewAccountUseCase(accountRepository.Object);

    // act
    await createNewAccountUseCase.Execute(account.ConvertToAccount());

    // assert
    accountRepository.Verify(m => m.Create(It.IsAny<Account>()), Times.Once);
}

然后可以在存储库 mock 上完成断言,以验证该方法是否按预期运行。

在您的问题的控制器测试中,您可以使用模拟用例,但您还需要确保它已注入到控制器中。

但是你的例子显示没有这样的注入。

以下示例创建控制器并显式注入依赖项

[Fact]
public async Task Create() {
    // arrange
    var account = new CreatingAccount();

    var accountRepository = new Mock<IAccountRepository>();
    accountRepository.Setup(m => m.Create(It.IsAny<Account>())).Returns(Task.CompletedTask);
    var createNewAccountUseCase = new CreateNewAccountUseCase(accountRepository.Object);

    var controller = new MyController(createNewAccountUseCase);

    // act
    await controller.CreateAccount(account);

    // assert
    accountRepository.Verify(m => m.Create(It.IsAny<Account>()), Times.Once);
}