测试类 A 中的方法是否已从类中的另一个方法调用

Test if method in ClassA has been called from another method in ClassA

可以使用 Moq and dependency injection 测试方法是否被调用。但是,是否可以测试 class 中的一个方法是否调用同一 class 中的另一个方法?

例如,我想测试如果我记录某个异常,是否也会记录一条信息消息。

方法是:

public void Error(string message, Exception exception, long logId = 0)
{
    var int32 = (int)logId;
    Info("Id was converted to an int so that it would fit in the log: " + logId, int32);
    Error(message, exception, int32);
}

这是我对其进行单元测试的尝试。测试失败,有什么办法可以解决吗?

void logging_an_error_with_a_long_id_also_logs_info()
{
    var mock = new Mock<ILogger>();
    var testedClass = new Logger();
    var counter = 0;

    testedClass.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue);

    mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>()));
}

由于 InfoError 方法在同一个 class (ClassA) 中,我不相信我可以将 ClassA 作为依赖项传递给 ClassA。那么它不需要测试吗?

您最多只能做到 Info virtual。这将允许您创建 Mock<Logger>,设置 CallBase = true,并验证是否调用了 Info

var mock = new Mock<Logger> 
{
    CallBase = true
};

mock.Object.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue);

mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>()));

这样,您仍在调用 Error 的实际实现,但您已使用 Moq 验证调用了 Info 方法。

感觉你在测试错误的东西。从 Error 方法调用 class 上的 Info 方法并不重要,重要的是 Info 方法的行为发生。它是如何发生的是 class.

的实现细节

如果我有一个数学 class 有两个函数:

public int Mult(int x, int y) {
    return x*y;
}

public int Sqr(int x) {
    return Mult(x,y);
}

我不会测试调用 Sqr 调用 Mult 函数,我会测试 Sqr(4)==16。该计算是在 Sqr 方法中进行,还是在 class.

的另一种方法中进行并不重要

虽然 @Andrew 的 可能是您所追求的,但嘲笑您正在测试的 class 往往会导致紧密耦合、脆弱的测试。

如果通过观察它的副作用来测试调用是不切实际的,那么这可能表明实现可以使用一些重构。