检查模拟中的更新实例
我有一个方法调用服务来检索对象的实例,更新实例,然后将实例保存回服务(其代码如下)。
我想知道的是,Moq 中是否有一种很好的方法来检查以下内容: -
- 保存回服务的实例是原始实例的修改版本
- 该实例已根据需要进行更新
我知道我可以使用 It.Is
来检查此处的第 2 点。但这样做会忽略第 1 点。
有没有一种干净的方法来实现这一目标?
类别代码:
public class MyClass
{
private readonly IThingService thingService;
public MyClass(IThingService thingService)
{
this.thingService = thingService;
}
public void SaveMyThing(MyThing myThing)
{
var existingThing = thingService.Get(myThing.Id);
existingThing.Name = myThing.Name;
thingService.Save(existingThing);
}
}
public class MyThing
{
public int Id { get; set; }
public string Name { get; set; }
}
public interface IThingService
{
MyThing Get(int id);
void Save(MyThing myThing);
}
测试代码:
[Test]
public void Save_NewName_UpdatedThingIsSavedToService()
{
// Arrange
var myThing = new MyThing {
Id = 42,
Name = "Thing1"
};
var thingFromService = new MyThing
{
Id = 42,
Name = "Thing2"
};
var thingService = new Mock<IThingService>();
thingService
.Setup(ts => ts.Get(myThing.Id))
.Returns(thingFromService);
thingService
.Setup(ts => ts.Save(**UPDATED-THING-FROM-SERVICE**))
.Verifiable();
var myClass = new MyClass(thingService.Object);
// Act
myClass.SaveMyThing(myThing);
// Assert
thingService.Verify();
}
I have a method that calls a service to retrieve an instance of an object, updates the instance then saves the instance back to the service (the code for this is below).
What I want to know is if there is a nice way in Moq to check the following:-
- That the instance that is being saved back to the service is a modified version of the original instance
- That the instance has been updated as desired
I know I can use It.Is<MyThing>(x => x.Name == newName)
to check for point 2 here. Doing this ignores point 1 though.
Is there a clean way to achieve this?
CLASS CODE:
public class MyClass
{
private readonly IThingService thingService;
public MyClass(IThingService thingService)
{
this.thingService = thingService;
}
public void SaveMyThing(MyThing myThing)
{
var existingThing = thingService.Get(myThing.Id);
existingThing.Name = myThing.Name;
thingService.Save(existingThing);
}
}
public class MyThing
{
public int Id { get; set; }
public string Name { get; set; }
}
public interface IThingService
{
MyThing Get(int id);
void Save(MyThing myThing);
}
TEST CODE:
[Test]
public void Save_NewName_UpdatedThingIsSavedToService()
{
// Arrange
var myThing = new MyThing {
Id = 42,
Name = "Thing1"
};
var thingFromService = new MyThing
{
Id = 42,
Name = "Thing2"
};
var thingService = new Mock<IThingService>();
thingService
.Setup(ts => ts.Get(myThing.Id))
.Returns(thingFromService);
thingService
.Setup(ts => ts.Save(**UPDATED-THING-FROM-SERVICE**))
.Verifiable();
var myClass = new MyClass(thingService.Object);
// Act
myClass.SaveMyThing(myThing);
// Assert
thingService.Verify();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果我理解正确的话,您想要验证传递给 ts.Save 的参数是否是从服务返回的实例。
如果是这样,除了验证
Name
值是否满足您的期望之外,还请检查引用相等性:If I understand correctly, you want to verify that the parameter passed to
ts.Save
is the instance returned from the service.If that's true, check reference equality in addition to verifying that the
Name
value meets your expectations:您已经差不多完成了:
主要区别是我还在第一个安装程序中添加了对
Verabilible()
的调用,然后添加了您已经提到过的It.Is
检查在你的回答中。由于存在谓词,只有当谓词计算结果为 true 时,Save 方法才会匹配,在这种情况下,Verify
调用会成功。然而,这个测试实际上测试了两件事(获取和保存)。为了避免断言轮盘,最好将其分成两个测试。
You are almost there:
The main difference is that I also added a call to
Verifiable()
to the first Setup, and then I added theIt.Is
check you already mentioned in your answer. Because of the predicate, the Save method will only be matched when the predicate evaluates to true, in which case theVerify
call succeeds.However, this test actually tests two things (Get and Save). To avoid Assertion Roulette, it would be better to split it up into two tests.
我同意马克的回答,但对你的第一个陈述有点困惑。您是否想查明该对象是否是相同的对象引用或对象类型? It.Is 只是确保参数是 MyThing 的类型,而不是确保它是对先前对象的实际引用。
如果您想拦截传递给模拟服务的值,则可以使用如下所示的回调,然后对结果对象执行您想要的任何断言:
I agree with Mark's answer but a bit confused by your first statement. Are you trying to find out if the object is the same object reference or object type? The It.Is just makes sure that parameter is the type of MyThing, not that it is the actual reference to your previous object.
If you want to intercept the value being passed to your mock service than you could use a callback like below and then do whatever assertions you want on the result object: