【发布时间】:2017-08-15 04:39:04
【问题描述】:
CallBase 是Moq (C# 单元测试库)中的一个函数,它允许轻松使用自定义代码挂钩函数调用,同时保留基本函数调用。在this SO post answer 上注明了它的用途和限制。
该帖子提到的主要限制是 CallBase 函数没有为 void 函数实现。
例如,假设我们要模拟这个 Component 类:
public class Component
{
public virtual void Do() { /* code */ }
}
然后我想使用 mock 调用 base 并运行自定义代码...
var mock = new Mock<Component>();
mock.Setup(m => m.Do())
// preserve base call (NOT AN OPTION SINCE VOID FUNCTION!)
.CallBase()
.Callback(() => {/* custom test code */});
// if Do() was not a void function, this would be supported by the library
一种不令人满意的替代方法是通过将 void 函数一分为二来更改我们正在测试的实际代码结构:
public class Component
{
public virtual void Do() {
this.DoInternal();
}
internal void DoInternal(){ /* code */ }
}
然后……
var mock = new Mock<Component>();
mock.Setup(m => m.Do())
.Callback(() =>
{
// my custom code...
// then call base
mock.Object.DoInternal();
});
这并不理想,因为它需要修改实际代码设计/结构纯粹是出于可测试性目的,而且如果 CallBase 由 Moq 本机支持,则需要更多的工作/代码。这种解决方法有替代方案吗?也许在库之外实现一个扩展来支持这个:
public static ICallbackResult<TMock> CallBase<TMock>(this ISetup<TMock> @this)
{
// not implemented - seems difficult given how little Moq
// exposes the underlying implementations which it overrides
// not sure about ICallbackResult<TMock> being what we'd want for return type...
// the return type of the actual CallBase function is IReturnsResult<TMock>, but
// that does not make much sense for a void function
}
让我知道你的想法!
【问题讨论】:
标签: c# .net unit-testing mocking moq