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

Hop*_*ppe 6 c# unit-testing moq

可以测试是否已使用Moq和依赖注入调用方法.但是,是否可以测试类中的一个方法是否在同一个类中调用另一个方法?

例如,我想测试一下,如果我记录某个异常,那么也会记录一条信息消息.

方法是:

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);
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试进行单元测试.测试失败了,有什么办法可以做到吗?

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>()));
}
Run Code Online (Sandbox Code Playgroud)

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

And*_*ker 7

你能做的最好的事情就是做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>()));
Run Code Online (Sandbox Code Playgroud)

这样,您仍然在调用实际的实现Error,但是您已经使用Moq来验证Info方法是否被调用.


for*_*rir 5

感觉你正试图测试错误的东西.InfoError方法调用类上的方法并不重要,重要的是Info方法的行为发生.它是如何发生的是该类的实现细节.

如果我有一个包含两个函数的数学类:

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

public int Sqr(int x) {
    return Mult(x,y);
}
Run Code Online (Sandbox Code Playgroud)

我不会测试那个Sqr叫做Mult函数的调用,我会测试Sqr(4)==16.如果计算发生在Sqr方法或类的另一个方法中,则无关紧要.

虽然@ Andrew的解决方案可能就是你所追求的,但是嘲笑你正在测试的课程往往导致紧密耦合的脆弱测试.

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