这是我的问题:
我有一个n层应用程序,我必须编写单元测试。单元测试用于业务层。
我有一个测试名为Insert()
的方法,这个方法使用两个受保护的继承方法,直接调用数据访问层的方法。
所以我为DAL制作了一个模拟对象。但是重要的是,在继承的(edit :) protected 方法中,它将使用来自DAL的另一个对象!似乎无法模仿这个!
以下是测试代码的方法:
public int Insert(MYOBJECT aMyObject)
{
//first inherited method use the FIRSTDALOBJECT so the mock object --> No problem
aMyObject.SomeField= FirstInherited();
//Second inherited method (see after) --> my problem
aMyObject.SomeOtherField = SecondInherited();
// Direct access to DALMethod, use FIRSTDALOBJECT so the mock -->No Problem
return this.FIRSTDALOBJECT.Insert(aMyObject);
}
这是SecondInherited方法:
protected string SecondInherited ()
{
// Here is my problem, the mock here seems not be possible for seconddalobject
return ( new SECONDDALOBJECT Sdo().Stuff());
}
这是单元测试方法代码:
[TestMethod()]
public void InsertTest()
{
BLLCLASS_Accessor target = new BLLCLASS_Accessor();
MYOBJECT aMyObject = new MYOBJECT { SomeField = null, SomeOtherField = 1 };
int expected = 1;
int actual;
//mock
var Mock = new Mock<DAL.INTERFACES.IFIRSTDALOBJECT>();
//Rec for calls
List<SOMECLASS> retour = new List<SOMECLASS>();
retour.Add(new SOMECLASS());
//Here is the second call (last from method to test)
Mock
.Setup(p => p.Insert(aMyObject))
.Returns(1);
// Here is the first call (from the FirstInherited())
Mock
.Setup(p => p.GetLast())
.Returns(50);
// Replace the real by the mock
target.demande_provider = Mock.Object;
actual = target.Insert(aMyObject);
Assert.AreEqual(/*Some assertion stuff*/);
}
感谢您阅读所有问题:-)希望它足够清楚。
答案 0 :(得分:3)
您的文字似乎表示 SecondInherited
为private
,而在代码示例中则为protected
。无论如何,如果它不是protected
,我建议将其访问限定符更改为第一步。
您可以创建一个仅用于测试目的的子类,并覆盖SecondInherited
那里以避免创建SECONDDALOBJECT
并返回一些适合您的测试的值。
通过这种方式,您可以编写您的第一个单元测试,对所测试的类进行最小的更改,从而最大限度地减少破坏的可能性。一旦您进行了单元测试,这些就可以让您安全地进行更多重构,最终实现更好(更可测试/可模拟)的设计,例如使用Dependency Injection或工厂。 (我可能更喜欢Abstract Factory而不是Factory Method,因为后者实际上会迫使你继续对测试类进行子类化。)
学习这项技术的基本的,强烈推荐的书(以及更多)是Working Effectively With Legacy Code。
答案 1 :(得分:2)
没有机会用MOQ嘲笑这个。 您有两种选择:
SECONDDALOBJECT
类SECONDDALOBJECT
的实例不是以它的方式创建的,而是以可以模拟的方式创建(工厂方法,DI,...)(首选!)