如何用moq模拟只有一个参数的方法
本文关键字:参数 方法 有一个 何用 moq 模拟 | 更新日期: 2023-09-27 18:07:07
我不熟悉嘲弄。我想测试GetById方法是否返回一个带有Id的User对象。在代码下面,我想测试GetById(10)是否返回id = 10的User。
我设置了moq(我希望它是正确的),但如何执行moq ?
谢谢,
[TestMethod]
public void MyMoq()
{
var userMock = new Mock<IUsers>();
userMock.Setup(x => x.GetById(10)).Returns(new User());
//After ?
new Users().GetById(10);
}
public interface IUsers
{
IUser GetById();
}
public IUser GetById(int id)
{
using (var context = ....)
{
//code here
//return user here
}
}
好吧,正如我在评论中所说的,我不清楚你要测试的代码是什么。我看到了两个选择。1) Users
类实现了IUsers
接口,你的目的是测试GetById(int)
方法的实现。在这种情况下,你不需要模拟'Users#GetById(id)'方法,你只需要调用它并检查结果。代码应该类似于:
interface IUser
{
int Id { get; }
}
class User : IUser
{
public int Id { get;set; }
}
interface IUsers
{
IUser GetById(int id);
}
class Users : IUser
{
public IUser GetById(int id)
{
// TODO: make call db call
// TODO: parse the result
// TODO: and return new User instance with all the data from db
return new User{ Id = id };
}
}
[TestMethod]
public void MyMoq()
{
// TODO: prepare/mock database. That's whole another story.
var users = new Users();
// act
var user = users.GetById(10);
// assert
Assert.AreEqual(10, user.Id);
}
2)你的Users#GetById(int)
方法应该调用IUsers#GetById(int)
并返回结果。在这种情况下,您需要创建IUsers
的mock(如问题中所示)并将其传递给Users
。代码应该是(抱歉可能存在重复):
interface IUser
{
int Id { get; }
}
class User : IUser
{
public int Id { get;set; }
}
interface IUsers
{
IUser GetById(int id);
}
class Users : IUser
{
private readonly IUser _users;
public Users(IUser users)
{
_users = users;
}
public IUser GetById(int id)
{
// next line of code is to be tested in unit test
return _users.GetById(id);
}
}
[TestMethod]
public void MyMoq()
{
var usersMock = new Mock<IUsers>();
usersMock.Setup(x => x.GetById(10)).Returns(new User());
var users = new Users(usersMock.Object);
// act
var user = users.GetById(10);
// assert
Assert.AreEqual(10, user.Id);
}
注。可以看看moq教程和单元测试的艺术书,Part 2 - Core techniques
(第47页)-存根,模拟等。
我不太确定你想测试什么。您还可以使用Mock类,其中包含一些您没有描述的方法。
然而,回答你关于嘲笑的问题。考虑这个类:
public class MyMoq : IUsers
{
private readonly Mock<IUsers> userMock;
public MyMoq(Mock<IUsers> userMock){
this.userMock = userMock;
}
[TestMethod]
public IUser GetById()
{
userMock.Setup(x => x.GetById(10)).Returns(new User());
//After ?
return new UsersDb().GetById(10);
}
}
使用它:
MyMoq moq = new MyMoq(new Mock<IUsers>());
User u = moq.GetById();
我在这个例子中的假设是Mock<IUsers>
是一个存储库,MyMoq
是一个服务类。另外,IUser
为实体接口,IUsers
为服务接口。
要测试userMock.Object
应该返回实际模拟的IUsers
对象。
var userMock = new Mock<IUsers>();
userMock.Setup(x => x.GetById(10)).Returns(new User());
var mockobject = userMock.Object;
//Returns your mocked new User() instance
var newUserObject = mockobject.GetById(10);
在上面的代码中,newUserObject
只创建了User
的一个新实例。要测试GetById
方法,需要再次调用它并Assert。
Assert.AreEqual(newUserObject.GetById(20).ID, 20); //Assume User has a property ID
建议:应该有更好的方法来创建User
实例
GetById应该在它自己的类中(可能称为Users),如果这是正在测试的内容。然后,用户可以在构造函数中接受上下文。然后模拟此上下文以返回存根数据。
总结一下
类用户实现IUsersUsers有一个带参数IContext的构造函数(或者这里的任何名称)测试类将模拟IContext,但不模拟IUsers。电话用户。GetById并检查输出是否正确。
设置上下文的方式取决于它是什么类型的上下文,但请参见https://cuttingedge.it/blogs/steven/pivot/entry.php?id=84。