c#Moq对象无效方法更改对象参数值

时间:2018-09-15 21:35:53

标签: c# mocking moq

我试图在单元测试中使用Mocks,但是我在下面的代码中苦苦挣扎。 我想以正确的方式从AppendName方法回调,以便正确测试此方法并实际更改模拟对象的名称。

public class GenericTests
{
   [TestMethod]
   public void TestMethod1()
   {
       IFile newFile = GetNewFile("Document").Object;
       newFile.AppendName();
       Assert.AreEqual("AppendedDocument", newFile.Name);
   }

   public Mock<IFile> GetNewFile(string name)
   {
       Mock<IFile> file = new Mock<IFile>();
       file.Setup(f => f.Name).Returns(name);
       file.Setup(f => f.Path).Returns(@"C:\Folder\" + name);
       file.Setup(f => f.AppendName()).Callback.....problem is here.....

        return file;
   }
}
public interface IFile
{
    string Name { get; set; }
    string Path { get; set; }
    void AppendName();
}
public class LocalFile : IFile
{
    public string Name { get; set; }
    public string Path { get; set; }
    public void AppendName()
    {
        this.Name = "AppendedDocument";
    }
} 

有人可以建议如何完成AppendName()的回调吗?请

1 个答案:

答案 0 :(得分:1)

您看到,接口IFile和类LocalFile是不同的类型。因此,默认情况下,我们无法从Mock<IFile>中复制LocalFile的实现。要进行测试,您可以添加下一个Callback呼叫:

public Mock<IFile> GetNewFile(string name)
{                
    Mock<IFile> file = new Mock<IFile>();
    file.CallBase = true;
    file.Setup(f => f.Name).Returns(name);
    file.Setup(f => f.Path).Returns(@"C:\Folder\" + name);
    file.Setup(f => f.AppendName()).Callback(() => file.Setup(f => f.Name).Returns(() => 
    {
        var localFile = new LocalFile();
        localFile.AppendName();
        return localFile.Name;
        // or just return "AppendedDocument"
    }));   

    return file;
} 

示例可行,但是我想这不是您所需要的。即使对于带有Mock<LocalFile>CallBase = true的{​​{1}},您也需要以某种方式清除属性设置。据我所知,Moq不允许这样做。我可能是错的。您可以根据相同的想法尝试下一个解决方法:

public virtual public string Name { get; set; }

我稍微改变了你的榜样。 public class GenericTests { [Test] public void TestMethod1() { IFile newFile = GetNewFile("Document"); newFile.AppendName(); Assert.AreEqual("AppendedDocument", newFile.Name); } public IFile GetNewFile(string name) { Mock<LocalFile> file = new Mock<LocalFile>(); file.CallBase = true; file.Object.AppendName(); // remember expected result before setting up the mock var appendDoc = file.Object.Name; file.Setup(f => f.Name).Returns(name); file.Setup(f => f.Path).Returns(@"C:\Folder\" + name); file.Setup(f => f.AppendName()) // change property behavior after call of AppendName .Callback(() => file.Setup(f => f.Name).Returns(appendDoc)); return file.Object; } } public interface IFile { string Name { get; set; } string Path { get; set; } void AppendName(); } public class LocalFile : IFile { public virtual string Name { get; set; } public virtual string Path { get; set; } public virtual void AppendName() { this.Name = "AppendedDocument"; } } 现在返回GetNewFile实例,并且IFile的成员变为虚拟成员。希望对您有所帮助。