【问题标题】:how to assert if a method has been called using nunit如何断言是否使用 nunit 调用了方法
【发布时间】:2013-12-02 15:33:46
【问题描述】:

是否可以断言方法是否已被调用?我正在测试以下方法,并且我想断言 _tokenManager.GetToken() 已被调用。我只想知道该方法是否已被调用,因为该方法不返回值。我正在使用起订量。

谢谢,

代码 sn-p

public void Subscribe(string code, string emailAddress, string columnKey)
{
    // Request authentication token
    var token = _tokenManager.GetToken(code, false);

    if (!_tokenValidator.Validate(token))
    {
        // Token has expired or invalid - refresh the token 
        token = _tokenManager.GetToken(code, true);
    }

    // Subscribe email
    _silverpopRepository.Subscribe(token.AccessToken, emailAddress, columnKey);
}

【问题讨论】:

  • 您看过 MOQ 或其他模拟框架吗?我相信NUnit有自己的,但我不熟悉?
  • 我已经更新了我的问题,我正在使用起订量。

标签: c# nunit moq


【解决方案1】:

你应该模拟TokenManagerTokenValidator,然后创建两个单元测试用例:

  • 案例 1:令牌已验证GetToken 仅被调用一次
  • 案例 2:令牌未验证GetToken 恰好被调用了两次

案例一:

[Test]
public void Subscribe_TokenIsValidated_GetTokenIsCalledOnce()
{
    // Arrange:
    var tokenManagerMock = Mock.Of<TokenManager>();

    var tokenValidatorMock = Mock.Of<TokenValidator>(x =>
        x.Validate(It.IsAny<Token>()) == true);

    var subscriber = new Subscriber
    {
        TokenManager = tokenManagerMock,
        TokenValidator = tokenValidatorMock
    };

    // Act:
    subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(),
        It.IsAny<string>());

    // Assert:
    Mock.Get(tokenManagerMock).Verify(x =>
        x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.Once);
}

案例 2:

[Test]
public void Subscribe_TokenIsExpiredOrInvalid_GetTokenIsCalledTwice()
{
    // Arrange:
    var tokenManagerMock = Mock.Of<TokenManager>();

    var tokenValidatorMock = Mock.Of<TokenValidator>(x =>
        x.Validate(It.IsAny<Token>()) == false);

    var subscriber = new Subscriber
    {
        TokenManager = tokenManagerMock,
        TokenValidator = tokenValidatorMock
    };

    // Act:
    subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(),
        It.IsAny<string>());

    // Assert:
    Mock.Get(tokenManagerMock).Verify(x =>
        x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.Exactly(2));
}

或者,您可以在不模拟 TokenValidator 的情况下创建单元测试,并验证 GetToken() 是否至少被调用过一次。但是,最好像第一个示例一样创建两个案例,因为我们正在测试所有代码路径。

// Arrange:
var tokenManagerMock = Mock.Of<TokenManager>();
var subscriber = new Subscriber {TokenManager = tokenManagerMock};

// Act:
subscriber.Subscribe(It.IsAny<string>(),
    It.IsAny<string>(),
    It.IsAny<string>());

// Assert:
Mock.Get(tokenManagerMock).Verify(x =>
        x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.AtLeastOnce);

在以下网址了解有关 Moq 验证的更多信息:

【讨论】:

    【解决方案2】:

    您可以使用验证方法使用 MOQ 进行验证。像这样:

    var tokenManagerMock = new Mock<ITokenManager>();
    var sut = new WhateverItIsCalled(tokenManagerMock.Object);
    sut.Subscribe("ssss", "example@example.com", "XXX");
    tokenManagerMock.Verify(m => m.GetToken(It.Is<string>(c => c == "ssss", It.Is<bool>(x => x == false)), Times.Once); 
    

    您需要能够以某种方式将令牌管理器传递到您正在测试的系统中。通常通过 ctor 或属性。

    我建议你使用 AutoFixture 之类的东西来消除“ssss”的丑陋并让事情变得更加干燥。

    您可能需要让令牌管理器模拟返回一些适当的东西,以通过验证。像这样的:

    var tokenManagerMock = new Mock<ITokenManager>();
    tokenManagerMock.Setup(m => m.GetToken(It.Is<string>(x => x == "ssss", It.IsAny<bool>()).Returns("XXXXXX");
    

    【讨论】:

    • 其实,除非有必要,我建议使用 It.IsAny()
    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多