c#Moq对象void方法,用于更改对象参数值

问题描述 投票:0回答:1

我正试图在我的单元测试中使用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";
    }
} 

有人可以请教如何完成Callnd for AppendName()???请

c# mocking moq
1个回答
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 = truepublic virtual public string Name { get; set; },你也需要以某种方式清除房产设置。据我所知,Moq不允许这样做。我错了。您可以根据相同的想法尝试下一个解决方法:

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实例,LocalFile成员变为虚拟。希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.