测试类 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>()));
}
由于 Info
和 Error
方法在同一个 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 往往会导致紧密耦合、脆弱的测试。
如果通过观察它的副作用来测试调用是不切实际的,那么这可能表明实现可以使用一些重构。
可以使用 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>()));
}
由于 Info
和 Error
方法在同一个 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 的
如果通过观察它的副作用来测试调用是不切实际的,那么这可能表明实现可以使用一些重构。