我想编写一个测试,该测试肯定会告诉您是否调用了模拟方法

时间:2019-09-07 12:05:39

标签: c# unit-testing moq verify

我有一个方法:

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())被调用?

1 个答案:

答案 0 :(得分:0)

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

[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);
}

然后可以在存储库模拟中进行断言,以验证该方法的行为是否符合预期。

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

但是您的示例未显示此类注入。

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

[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);
}