代码之家  ›  专栏  ›  技术社区  ›  jmzagorski

FakeItEay:从返回null的受保护方法获取参数

  •  1
  • jmzagorski  · 技术社区  · 10 年前

    我正在尝试测试在受保护的虚拟方法中传递的参数,以确保正确设置了财产。然而,下面的语句没有设置我的变量,但FakeItEay确实认识到正在进行此调用。我的语法不正确吗?

    单元测试

    EmailEventArgs argsInEvent = null;
    
    A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
        .Invokes(i => argsInEvent = i.GetArgument<EmailEventArgs>(0))
        .MustHaveHappened(Repeated.Exactly.Once);
    

    存储库中的方法

    private void onSaveSetupEmailArgs(string callerName, int pk)
    {
        EmailEventArgs args = new EmailEventArgs();
    
        // ..set property logic
    
        OnSaveRequest(args); // the protected virtual method
    }
    
    1 回复  |  直到 10 年前
        1
  •  4
  •   Blair Conrad    10 年前

    如果没有完整的测试,很难判断到底发生了什么。典型的测试模式为:

    1. 制造假货
    2. 配置fake以设置参数的捕获
    3. 执行生产代码,该代码应使用假的,以及
    4. 然后验证是否进行了呼叫。

    我看不出你把 生产代码,但您的 A.CallTo 似乎两者都在努力 配置该方法并验证是否进行了调用。自从你 说 MustHaveHappened 通过,我猜这段代码 在调用生产代码之后。类似于:

    var repository = A.Fake<IRepository>();
    
    repository.SaveSetup(…);
    
    EmailEventArgs argsInEvent = null;
    
    A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
        .Invokes(i => argsInEvent = i.GetArgument<EmailEventArgs>(0))
        .MustHaveHappened(Repeated.Exactly.Once);
    

    这将不起作用(当然,您知道这一点,或者您不会问问题),因为您正在配置 Invokes 之后 生产代码已运行(并且 OnSaveRequest 电话已经打到了假货上)。

    你应该有这样的东西:

    // Arrange
    EmailEventArgs argsInEvent = null;
    
    var repository = A.Fake<IRepository>();
    
    A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
        .Invokes(i => argsInEvent = i.GetArgument<EmailEventArgs>(0));
    
    // Act
    repository.SaveSetup(…);
    
    // Assert
    A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
        .MustHaveHappened(Repeated.Exactly.Once);
    
    // and maybe do something with argsInEvent