开发者

Testing repository method

As the title suggests I'm trying to 开发者_运维百科test a method, unfortunately I appear to be going wrong some where. The method should only return customers that have and ID = 1

Here is my test

        [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());
        }

Here is the repository method I'm trying to test

        public IQueryable<GymSession> GetWorkoutDatesByCustomerId(int userId)
    {
        var gymSess = db.GymSessions.Where<GymSession>(g => g.Customer.CustomerId == userId);

        return gymSess;
    }

The idea is that setup has all the customers, and the method then filters them. The count never seems to apply the filter. Any ideas?


It appears that you really want to stub the call to db.GymSessions and that you should test a concrete GymSessionRepository instance. Traditionally, there are two ways to do this (apart from intercepting calls using aspect-oriented programming):

1) Give your repository an explicit dependency on db and require it in the repository constructor. Here's what I mean, where I'm using IDatabase to represent 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) (Less desirable, but sometimes necessary) Expose the method you want to stub as a virtual member, mock the concrete object you're testing, and stub the behavior directly on the class under test:

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());

Depending on the mocking framework, the second technique is known as using a transparent or partial mock. If you find yourself using it often, it may be a sign that your code is overly-coupled (and it can get confusing fast).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜