[英]c# Moq objects void method that changes objects parameter value
I'm trying to use Mocks in my Unit testing but I struggle with below code. 我试图在单元测试中使用Mocks,但是我在下面的代码中苦苦挣扎。 I want to Callback from AppendName method in right way so that this method is correctly tested and mocked object name is actually changed.
我想以正确的方式从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";
}
}
Can someone please advice how to complete Callback for AppendName() ??? 有人可以建议如何完成AppendName()的回调吗? please
请
You see, interface IFile
and class LocalFile
are different types. 您会看到,接口
IFile
和类LocalFile
是不同的类型。 So we can't make from Mock<IFile>
reproduce the implementation from LocalFile
by default. 因此,默认情况下,我们无法从
Mock<IFile>
复制LocalFile
的实现。 To make your test work you can add next Callback
call: 要进行测试,您可以添加下一个
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;
}
Example works, however it is not what you need, I suppose. 示例可以工作,但是我想这不是您所需要的。 Even for
Mock<LocalFile>
with CallBase = true
and public virtual public string Name { get; set; }
即使对于
CallBase = true
Mock<LocalFile>
以及public virtual public string Name { get; set; }
public virtual public string Name { get; set; }
public virtual public string Name { get; set; }
you would need to clear property setup somehow. public virtual public string Name { get; set; }
您需要以某种方式清除属性设置。 As far as I know Moq doesn't allow this. 据我所知,Moq不允许这样做。 I can be wrong.
我可能是错的。 You can try the next workaround, based on the same idea:
您可以根据相同的想法尝试下一个解决方法:
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";
}
}
I have changed your example a little bit. 我已经稍微改变了你的榜样。
GetNewFile
now returns IFile
instance and members of the LocalFile
became virtual. GetNewFile
现在返回IFile
实例,并且LocalFile
成员变为虚拟成员。 Hope it helps. 希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.