正如标题所暗示的那样,我正试图测试一种方法,不幸的是我似乎在某些地方出错了。该方法应仅返回具有ID = 1
的客户这是我的测试
[TestMethod]
public void Returns_Correct_Number_Of_Workout_Dates_For_Valid_UserId()
{
//Arrange
List<GymSession> gymSessions = new List<GymSession>();
Customer cust = new Customer();
cust.CustomerId = 1;
gymSessions.Add(new GymSession() { Customer = cust, SessionId = 1, Date = new DateTime(2010, 1, 1) });
gymSessions.Add(new GymSession() { Customer = cust, SessionId = 2, Date = new DateTime(2010, 1, 2) });
gymSessions.Add(new GymSession() { SessionId = 3, Date = new DateTime(2010, 1, 3) });
gymSessions.Add(new GymSession() { Customer = cust, SessionId = 4, Date = new DateTime(2010, 1, 4) });
var mockRepos = new Moq.Mock<IGymSessionRepository>();
mockRepos.Setup(g => g.GymSession()).Returns(gymSessions.AsQueryable());
//Act
var result = mockRepos.Object.GetWorkoutDatesByCustomerId(1);
//Assert
Assert.AreEqual(3, result.Count());
}
这是我正在尝试测试的存储库方法
public IQueryable<GymSession> GetWorkoutDatesByCustomerId(int userId)
{
var gymSess = db.GymSessions.Where<GymSession>(g => g.Customer.CustomerId == userId);
return gymSess;
}
我们的想法是,安装程序拥有所有客户,然后该方法会对其进行过滤。计数似乎永远不会应用过滤器。有什么想法吗?
答案 0 :(得分:1)
您似乎确实想要将调用存根到db.GymSessions
,并且您应该测试具体的GymSessionRepository
实例。传统上,有两种方法可以做到这一点(除了使用面向方面编程拦截调用):
1)为您的存储库提供对db
的显式依赖,并在存储库构造函数中要求它。这就是我的意思,我使用IDatabase
来表示db
:
public class GymSessionRepository: IGymSessionRepository {
private IDatabase db;
public GymSessionRepository(IDatabase db) {
this.db = db;
}
}
// Then in your test ...
var mockDb = new Moq.Mock<IDatabase>();
mockDb.Setup(d => d.GymSessions()).Returns(gymSessions.AsQueryable());
GymSessionRepository repository = new GymSessionRepository(mockDb);
// ... and so on
2)(不太理想,但有时是必要的)将您想要存根的方法公开为虚拟成员,模拟您正在测试的具体对象,并直接在被测试的类上存根行为:
public class GymSessionRepository {
// Because this is virtual, you can override it in your mock object
protected virtual List<GymSession> GymSessions() {
return this.db.GymSessions.AsQueryable();
}
}
// In your test code here: notice the mock object is your concrete class,
// because your test targets another method on that class, not a method
// on an arbitrary implementation (like a mock based on its interface)
var mockRepos = new Moq.Mock<GymSessionRepository>();
// Override its virtual method; take control for your test
mockRepos.Setup(g => g.GymSessions()).Returns(gymSessions.AsQueryable());
根据模拟框架,第二种技术称为使用transparent或partial模拟。如果您经常使用它,则可能表明您的代码过度耦合(并且可能会让您感到困惑)。