【问题标题】:Unit Testing One Method Calls Another Method in the Same Class单元测试一个方法调用同一个类中的另一个方法
【发布时间】:2020-05-28 15:40:09
【问题描述】:

我在一个类上有两个公共方法,都从外部代码调用,但其中一个方法也调用另一个。我想对一个方法进行单元测试,然后验证它是否调用了同一个类中的另一个公共方法,然后我会有单独的测试来测试另一个第二种方法。结构看起来像这样:

public CalculatedResult GetCalculatedDetailsById(Guid id)
{
  var entity = _entityRepository.GetEntity(id);
  if(entity == null)
  {
    throw new NotFoundException();
  }

  return GetCalculatedDetailsForEntity(entity);
}

public CalculatedResult GetCalculatedDetailsForEntity(Entity entity)
{
  var supplementalData = _someDependency.GetSupplementalData(entity.Property);
  var calculatedData = _someOtherDependency.ProcessEntity(entity, supplementalData);

  _cache.Set(calculatedData, expiry);

  return calculatedData;
}

对于GetCalculatedDetailsForEntity,我将模拟依赖项,验证它们是否被正确调用,验证缓存是否设置正确,验证返回值是否符合所提供的输入和模拟值的预期值。

对于GetCalculatedDetailsById,我将模拟存储库依赖项,测试它是否按预期调用了GetEntity,并在必要时抛出异常。然后我想验证它是否使用预期的实体对象调用GetCalculatedDetailsForEntity,但我不想验证它是否执行GetCalculatedDetailsForEntity 中的所有逻辑,因为我已经在其他地方进行了测试。

是否可以为 GetCalculatedDetailsById 测试模拟 GetCalculatedDetailsForEntity,以便我可以验证它是否按预期被调用?

我的技术栈是 .NET Core、XUnit 和 Moq。

【问题讨论】:

    标签: unit-testing .net-core mocking moq xunit.net


    【解决方案1】:

    您可以对第一种方法执行以下操作,因为您基本上是在根据我阅读您的问题的方式进行测试以查看没有引发异常:

    [Test]
    public void TestNoExceptionIsThrownByMethodUnderTest()
    {
        var CalculatedResult = new CalculatedResult();
    
        try
        {
            var calculatedResult = CalculatedResult.GetCalculatedDetailsById(someid);
        }
        catch (Exception ex)
        {
            check here to see what exception type is. If NotFoundException then
            Assert.Fail("NotFoundException Thrown");
            Else exception was thrown in method being called which your other method should handle
        }
    }
    

    对于你的第二种方法(GetCalculatedDetailsForEntity)可以像你说的那样运行单独的测试。

    【讨论】:

    • 是的,我确实想到了 - 设置所有模拟以确保返回对象。它的实际方法有点复杂,需要大量的设置。希望有更简洁的解决方案。
    【解决方案2】:

    如果您使用的是起订量框架,那么您可以使用Times.Once(), or Times.Exactly(1):

    例如

    mockContext.Verify(x => x.GetCalculatedDetailsForEntity(It.IsAny<Entity>()), Times.Once());
    

    参考:请看here.希望对你有帮助!

    【讨论】:

    • 在这种情况下,我没有模拟类,至少对于我要验证的方法来说没有。被测方法和我试图验证的方法都在类上。我无法模拟目标类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 2020-08-24
    • 2011-01-14
    相关资源
    最近更新 更多