如何解决如何设置静态方法返回的对象?单元测试 合同包装器替代方案依赖抽象单元测试
public class ClassWithAMethod
{
public static void A(string email)
{
var b = SomeClass.Staticmethod();
var c = b.GetUser(x => x.Email == email);
if (c != null)
{
throw new Exception();
}
}
}
public void Abc()
{
ClassWithAMethod.A("123@gmail.com");
}
所以我需要模拟对象 b
和设置方法 GetUser
但我该怎么做?
解决方法
如果不修改,我认为这是不可能的。
稍微修改和不间断的更改可能是添加一个可选参数 bGetter
来获取 b。
然后,您可以在单元测试中创建自己的 bGetter
。
public class ClassWithAMethod
{
public static void A(string email,Func<B> bGetter = null)
{
var b = null == bGetter ? SomeClass.StaticMethod() : bGetter();
var c = b.GetUser(x => x.Email == email);
if (c != null)
{
throw new Exception();
}
}
}
,
正如谚语所说:你可以用另一个间接级别解决所有问题,除了太多间接级别的问题 Reference
通过引入包装器/适配器,您的解决方案变得更加loosely coupled。
合同
那么,首先介绍一下如下界面:
public interface IBFactory
{
B Create();
}
包装器
让我们创建包装器:
public class BWrapper: IBFactory
{
public B Create()
{
return SomeClass.StaticMethod();
}
}
替代方案
在 C# 8 的情况下,您可以依靠 default implementation in interface 功能将前两个步骤合二为一:
public interface IBFactory
{
public B Create()
{
return SomeClass.StaticMethod();
}
}
依赖抽象
现在让我们修改 ClassWithAMethod
类以依赖于 IBFactory
:
public class ClassWithAMethod
{
private readonly IBFactory _bFactory;
public ClassWithAMethod(IBFactory bFactory)
{
this._bFactory = bFactory;
}
public static void A(string email)
{
var b = this._bFactory.Create();
var c = b.GetUser(x => x.Email == email);
if (c != null)
{
throw new Exception();
}
}
}
您可以将 BWrapper
注册为 DI 容器中 IBFactory
的默认实现。或者,如果您不使用 DI 或 C# 8,那么您可以指定一个依赖 BWrapper
的无参数构造函数。请记住,不建议使用这种方法。这更像是最后的手段。
public class ClassWithAMethod
{
private readonly IBFactory _bFactory;
public ClassWithAMethod()
{
this._bFactory = new BWrapper();
}
public ClassWithAMethod(IBFactory bFactory)
{
this._bFactory = bFactory;
}
...
}
单元测试
现在您也可以模拟该依赖项。
var bFactoryMock = new Mock<IBFactory>();
bFactoryMock.Setup(factory => factory.Create()).Returns(...);
var SUT = new ClassWithAMethod(bFactoryMock.Object);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。