背景 我的应用程序通过代理服务器消耗WCF服务。我必须对我的实现进行单元测试,它会消耗服务并且处理正确完成。
要测试的方法
public class MyClass
{
private ManagerServiceClientImpl myclient;
public void MethodToBeTested();
{
var result = GetServiceData();
if(result!=null)
//some processing
}
}
private MyObject GetServiceData()
{
myclient = ServiceLocator.Current.GetInstance<ManagerServiceClientImpl>();
if(myclient.ConnectToService() && myclient.MyServiceClient.IsConnected)
return myclient.GetData();
else
return null;
}
这是由外部来源提供的,因此我无权对其进行修改
public class ManagerServiceClientImpl
{
public ServiceClient MyServiceClient { get; private set; }
public bool ConnectToService()
}
如何模拟ManagerServiceClientImpl
没有界面或方法未标记为虚拟
到目前为止我尝试了什么。
[TestMethod]
public void IsServiceConnected_GetData()
{
//Arrange
ManagerServiceClientImpl clientImpl =
MockRepository.GenerateMock<ManagerServiceClientImpl>();
ServiceLocator.Expect(x => x.GetInstance<ManagerServiceClientImpl>())
.Return(clientImpl);
var testData= new MyObject
{
ID = "Test1",
Name ="test",
}
//Act
_myClass.MethodToBeTested();
//Assert
stubService.AssertWasCalled(h => h.SaveAllChanges());
}
注意:使用Rhino.Mocks。这是我第一次使用Rhino mocks
答案 0 :(得分:4)
正如Amittai Shapira所说,你可以使用支持它的单元测试框架在没有接口的情况下模拟它,我正在使用Typemock Isolator,我为你的代码创建了一个示例测试:
我创建了一个MyClass实例,并使用Typemock的一个功能来模拟非公共方法来更改GetServiceData的返回值
[TestMethod]
public void TestMethod1()
{
var testData = new MyObject
{
ID = "Test1",
Name = "test",
};
var realObj = new MyClass();
Isolate.NonPublic.WhenCalled(realObj, "GetServiceData").WillReturn(testData);
Isolate.NonPublic.WhenCalled(realObj, "SaveAllChanges").CallOriginal();
realObj.MethodToBeTested();
Isolate.Verify.NonPublic.WasCalled(realObj, "SaveAllChanges");
}
答案 1 :(得分:2)
为了使用RhinoMocks(或Moq,或任何其他“约束”模拟框架),您正在模拟的类型必须支持要模拟的成员的继承。这意味着它必须是一个接口,或者成员必须是虚拟/抽象的。没有它,这些框架就无法完成他们在运行时生成代理中间人所需要做的事情。有关更多详细信息,请参阅我的博客文章,了解.NET模拟框架如何在幕后工作:https://www.wrightfully.com/how-net-mocking-frameworks-work
你可以做的是在你自己的类中创建包装其他服务的方法,这样你就可以模拟你的方法并让它们返回你需要的任何东西,完全绕过服务。