模拟处于同一界面并在其中调用的测试方法

时间:2015-02-06 05:32:46

标签: c# mocking

假设我有以下成员的界面

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");
    }
}

3 个答案:

答案 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 TestMethodATestMethodB(取决于设计决定,例如内聚),然后将包含TestMethodA的接口注入class - 然后你可以按照自己的意愿嘲笑它。

答案 2 :(得分:0)

谢谢Mr.Wombat。

在实际应用程序中充当相同的场景。我不得不为MethodA设置很多东西并使用它。如果它是虚拟的,我能够嘲笑它。

大多数Mock框架都不会模拟非虚方法。选项是JustMock Commercial许可证,它可以模拟非虚拟方法。