假设我有以下成员的界面
public interface IDataService
{
Employee TestMethodA();
Employee TestMethodB();
}
public class DataService : IDataService
{
public Employee TestMethodA()
{
return new Employee() {Id = 10, Name = "Montu Pradhan"};
}
public Employee TestMethodB()
{
var emp = TestMethodA();
return emp;
}
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
然后我需要通过模拟MethodA来测试MethodB方法。我有以下夹具,但控件仍然进入MethodA。我正在使用JustMock作为测试框架。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestInterfaceMock()
{
var pensionMock = Mock.Create<DataService>();
Mock.Arrange<Employee>(() => pensionMock.TestMethodA())
.Returns(new Employee() {Id = 101,Name = "Mock Employee"});
var result = pensionMock.TestMethodB();
Assert.AreEqual(result.Name, "Mock Employee");
Assert.AreEqual(result.Id, "Mock Employee");
}
}
答案 0 :(得分:0)
如果是Virtual,我可以模拟MethodA。然后调试器将返回Mock.Arrange中的Reuturns()块中的对象....
答案 1 :(得分:0)
您无法模拟TestMethodA()
,因为它与您正在测试的同一个类 - 您可以使TestMethodA()
为虚拟,创建一个覆盖TestMethodA()
的派生类(模拟它)和测试TestMethodB()
在测试者类中没有变化。
public class DataService : IDataService
{
public virtual Employee TestMethodA()
{
return new Employee() {Id = 10, Name = "Montu Pradhan"};
}
}
public class TestableDataService : DataService
{
private Employee e;
public TestableDataService(Employee returningEmployee)
{
this.e = returningEmployee;
}
public override Employee TestMethodA()
{
return e;
}
}
现在您可以测试TestMethodB()
:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestInterfaceMock()
{
var testableSut = new TestableDataService(new Employee() {Id = 101,Name = "Mock Employee"});
var result = testableSut.TestMethodB();
Assert.AreEqual(result.Name, "Mock Employee");
Assert.AreEqual(result.Id, "101");
}
}
另一种选择是将IDataService
拆分为两个接口containsig TestMethodA
和TestMethodB
(取决于设计决定,例如内聚),然后将包含TestMethodA
的接口注入class - 然后你可以按照自己的意愿嘲笑它。
答案 2 :(得分:0)
谢谢Mr.Wombat。
在实际应用程序中充当相同的场景。我不得不为MethodA设置很多东西并使用它。如果它是虚拟的,我能够嘲笑它。
大多数Mock框架都不会模拟非虚方法。选项是JustMock Commercial许可证,它可以模拟非虚拟方法。