ebb*_*ebb 4 c# unit-testing moq mocking
我刚刚开始使用Moq进行单元测试/模拟,并遇到了问题..
我有一个名为"CustomerService"的服务层,它有以下代码:
public interface ICustomerService
{
Customer GetCustomerById(int id);
}
public class CustomerService : ICustomerService
{
private IRepository<Customer> customerRepository;
public CustomerService(IRepository<Customer> rep)
{
customerRepository = rep;
}
public Customer GetCustomerById(int id)
{
var customer = customerRepository.Get(x => x.CustomerId == id);
if (customer == null)
return null;
return customer;
}
}
Run Code Online (Sandbox Code Playgroud)
我的存储库类是通用的,并且遵循:
public interface IRepository<T> : IDisposable where T : class
{
T Get(Expression<Func<T, bool>> predicate);
}
public class Repository<T> : IRepository<T> where T : class
{
private ObjectContext context;
private IObjectSet<T> objectSet;
public Repository()
: this(new demonEntities())
{
}
public Repository(ObjectContext ctx)
{
context = ctx;
objectSet = context.CreateObjectSet<T>();
}
public T Get(Expression<Func<T, bool>> predicate)
{
T entity = objectSet.Where<T>(predicate).FirstOrDefault();
if (entity == null)
return null;
return objectSet.Where<T>(predicate).FirstOrDefault();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (context != null)
{
context.Dispose();
context = null;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在是我的问题..如何进行单元测试以检查我的GetCustomerById是否返回null?
已经尝试过:
[TestMethod]
public void GetCustomerTest()
{
const int customerId = 5;
var mock = new Mock<IRepository<Customer>>();
mock.Setup(x => x.Get(z => z.CustomerId == customerId))
.Returns(new Customer());
var repository = mock.Object;
var service = new CustomerService(repository);
var result = service.GetCustomerById(customerId);
Assert.IsNotNull(result);
}
Run Code Online (Sandbox Code Playgroud)
没有运气......
您需要将Repository<T>.Get方法设置为虚拟,以便Moq可以覆盖它并返回您设置的值:
public virtual T Get(Expression<Func<T, bool>> predicate)
Run Code Online (Sandbox Code Playgroud)
在你的测试中,改变
mock.Setup(x => x.Get(z => z.CustomerId == customerId))
.Returns(new Customer());
Run Code Online (Sandbox Code Playgroud)
至
mock.Setup(x => x.Get(It.IsAny<Expression<Func<Customer, bool>>>()))
.Returns(new Customer());
Run Code Online (Sandbox Code Playgroud)
它表示返回Customer任何Expression<Func<Customer, bool>>传入的新内容.理想情况下,您将测试一个特定的表达式,但根据这个SO问题的接受答案,Moq不能这样做.
如果您想测试您的服务层没有Customer对存储库返回的任何意外做任何事情,而不是测试以查看是否有任何 Customer返回,您可以设置模拟Customer(确保使CustomerId属性为虚拟)并断言Customer由服务层返回的具有预期的属性.
[TestMethod]
public void GetCustomerTest()
{
const int customerId = 5;
var mockCustomer = new Mock<Customer>();
mockCustomer.SetupGet(x => x.CustomerId)
.Returns(customerId);
var mock = new Mock<IRepository<Customer>>();
mock.Setup(x => x.Get(It.IsAny<Expression<Func<Customer, bool>>>()))
.Returns(mockCustomer.Object);
var repository = mock.Object;
var service = new CustomerService(repository);
var result = service.GetCustomerById(customerId);
Assert.AreEqual(customerId, result.CustomerId);
}
Run Code Online (Sandbox Code Playgroud)
HTH