使用Moq在另一个方法内调用Intercep接口方法

时间:2014-02-20 17:03:51

标签: c# unit-testing moq

我有一个界面:

public interface ISomeInterface
{
  public string ReturnSomeString();
}

和界面实现:

public class SomeInterface: ISomeInterface
{
     public string ReturnSomeString()
     {
        return "Hello";
     }
}

在另一种方法中,我调用了这个接口实现:

public class SomeClass
{

    public string DoTheCall()
    {
       ISomeInterface someInterface = new SomeInterface();
       return someInterface.ReturnSomeString();

    }
}

现在我希望Moq每次调用ReturnSomeString都会返回“Hello World”

我试过这个:

[TestClass]
public class Test
{
    [TestMethod]
    public void SomeTest()
    {
        var mock = new ISomeInterface();
        mock.Setup(x => x.ReturnSomeString()).Returns("Hello World!!!");            

        SomeClass sc = new SomeClass();

        Assert.IsTrue(sc.ReturnSomeString(), "Hello World!!!");
    }
}

但始终完成原始接口方法调用。 我不想使用构造函数注入或类似的东西,有没有办法告诉Moq每次调用接口或实现(从任何地方)应该返回模拟的字符串?

3 个答案:

答案 0 :(得分:4)

这将是构造函数注入。

 public class SomeClass
    {
    ISomeInterface someInterface;
        public SomeClass(ISomeInterface inter)
        {
           this.someInterface = inter;
        }
        public string DoTheCall()
        {
           return someInterface.ReturnSomeString();
        }
    }

[TestClass]
public class Test
{
    [TestMethod]
    public void SomeTest()
    {
        var mock = new ISomeInterface();
        mock.Setup(x => x.ReturnSomeString()).Returns("Hello World!!!");            

        SomeClass sc = new SomeClass(mock.Object);

        Assert.IsTrue(sc.ReturnSomeString(), "Hello World!!!");
    }
}

否则你可以进行属性注入,基本上就是这样(请注意你应该处理null属性)

 public class SomeClass
    {
      public ISomeInterface someInterface{get;set;}

        public string DoTheCall()
        {
           return someInterface.ReturnSomeString();
        }
    }

[TestClass]
    public class Test
    {
        [TestMethod]
        public void SomeTest()
        {
            var mock = new ISomeInterface();
            mock.Setup(x => x.ReturnSomeString()).Returns("Hello World!!!");            

            SomeClass sc = new SomeClass {someInterface = mock.Object};

            Assert.IsTrue(sc.ReturnSomeString(), "Hello World!!!");
        }
    }

答案 1 :(得分:3)

否 - 您的方法显式实例化类,而Moq无法修改现有类。

您可以选择:

  • 通过构造函数,属性或方法参数(不是你想要的)进行适当的依赖注入
  • 使用工厂方法调用替换new以允许返回不同的对象
  • 使用像Fakes
  • 这样更重的东西

答案 2 :(得分:1)

您必须进行一些更改才能使代码可测试:

public class SomeClass
{
    private readonly ISomeInterface _someInterface;
    public SomeClass(ISomeInterface someInterface){
      _someInterface= someInterface;
    }

    public string DoTheCall()
    {
       return _someInterface.ReturnSomeString();

    }
}

测试:

[TestClass]
public class Test
{
    [TestMethod]
    public void SomeTest()
    {
        var mock = new Mock<ISomeInterface>();
        mock.Setup(x => x.ReturnSomeString()).Returns("Hello World!!!");            

        SomeClass sc = new SomeClass(mock.Object);

        Assert.IsTrue(sc.ReturnSomeString(), "Hello World!!!");
    }
}

我认为它可以用来测试作品。