我有一个控制器,其中包含一个business
类,内部具有datahandler
的依赖关系。为了测试该业务类,我需要模拟datahandler
。设置完成后,我正在分配商务课程' datahandler
与模拟datahandler
。但在调试时,商务舱' datahandler
显示为null,我知道我应该使用构造函数来注入模拟对象。但是可以在不使用任何构造函数注入的情况下执行它吗?任何正文可以帮助我吗?
我的商务舱:
public class FooBusiness
{
public static BarDataHandler _barDatahandler = new BarDataHandler();
...
}
测试类:
public class FooBusinessTest
{
...
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x=>x.Search(It.IsAny<int>).Returns(1);
...
FooBusiness _fooBusiness = new FooBusiness();
FooBusiness._barDatahandler = _mockedBarDataHandler.Object;
//Act
...
}
}
答案 0 :(得分:0)
您需要将dataHandler依赖项注入FooBusiness
如果不存在BarDataHandler
,您需要提取一个界面。
interface IBarDataHandler
{
string GetUserToken(int id);
}
public class BarDataHandler : IBarDataHandler
{
public string GetUserToken(int id)
{
// to do :read from db and return
}
}
并向FooBusiness
类添加一个构造函数,该类接受IBarDataHandler
的实现。
public class FooBusiness
{
IBarDataHandler barDataHandler;
public FooBusiness(IBarDataHandler barDataHandler)
{
this.barDataHandler=barDataHandler
}
public string GetUserToken(int id)
{
return this.barDataHandler.GetUserToken(id);
}
}
您可以使用任何一个依赖注入框架(如Unity / Ninject / StructureMap)来解析应用程序运行时的具体实现。
您可以使用任何模拟框架(如 Moq )来模拟单元测试中的IBarDataHandler虚假实现。
答案 1 :(得分:0)
正如我所提到的,有多种方法可以满足您的需求。 我个人更喜欢Shyju的答案(构造函数注入),但如果你不能改变构造函数,你仍然可以通过设置属性来改变实现:
商务舱:
public class FooBusiness
{
private IBarDataHandler _barDatahandler = new BarDatahandler();
public IBarDataHandler BarDatahandler
{
get { return _barDatahandler; }
set { _barDatahandler = value; }
}
public int Search(int a)
{
return _barDatahandler.Search(a);
}
}
测试类:
public class FooBusinessTest
{
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x => x.Search(It.IsAny<int>).Returns(1);
FooBusiness fooBusiness = new FooBusiness();
fooBusiness.BarDatahandler = _mockedBarDataHandler.Object;
//Act
}
}
如果您担心重构实现,最好先设置所有测试。之后你可以用更安全的感觉重构:)