2009-05-19 46 views
6

Tôi có một phương pháp hành động như thế này trong bộ điều khiển của tôiLàm cách nào để moq ISingleResult? Tôi có nên không? hoặc có một phương pháp tốt hơn?

public ActionResult Index() 
{ 
    using (NorthwindDataContext db = new NorthwindDatacontext()) 
    { 
     var results = db.GetRecordSets(arg1, ....).ToList(); 
     // use results as list 
    } 

    return View(); 
} 

và tôi muốn bắt đầu thực hiện các bài kiểm tra cho nó (vâng, sau khi nó được xây dựng, không phải trước ... nhưng mã đã được viết trước khi tôi bắt đầu sử dụng TDD như vậy ...)

và tôi đã tìm ra rằng việc thêm một tài sản như thế này với bộ điều khiển

public delegate NorthwindDatacontext ContextBuilderDelegate(); 

public ContextBuilderDelegate ContextBuilder { get; set; } 

tôi có thể thêm vào một cái gì đó constructor như thế này ...

0.123.
ContextBuilder =() => new NorthwindDatacontext(); 

sau đó tôi có thể kiểm tra ActionMethod thiết lập thuộc tính ContextBuilder với một mô hình của NorthwindDataContext

var controller    = new MyController(); 
var mockDataContext   = new Mock<NorthwindDatacontext>(); 
controller.ContextBuilder =() => mockDataContext.Object; 

... Nhưng tôi thấy không có cách nào để sử dụng này bởi vì tất cả các phương pháp sử dụng NorthwindDataContext ISingleResult như returnType và tôi không thể tìm cách tạo đối tượng với giao diện đó. Tôi đã thử điều này

var theResult     = new List<GetRecordSetsResult>(); 
// fill the data structure here with the provided result... 

mockDataContext.Setup(c => c. GetRecordSets()).Returns(theResult as 
              ISingleResult<GetRecordSetsResult>); 

nhưng nó không hoạt động vìResult là null khi được chuyển sang ISingleResult.

Có cách nào để tạo đối tượng ISingleResult để kiểm tra theo cách này hoặc tôi đang làm cách không chính xác để làm việc ở đây?

Cảm ơn trước

+0

Cảm ơn câu hỏi của bạn và câu trả lời đầu tiên đã giúp tôi giải quyết vấn đề. – Odd

Trả lời

3

ToList() là một phương pháp mở rộng cho IEnumerable, đó là dễ dàng để chế nhạo, bởi vì nó chỉ có một phương pháp viên - GetEnumerator().

Tuy nhiên bạn có thể có vấn đề chế giễu lớp NorthwindDataContext, nếu phương pháp của nó không phải là ảo ...

Anyways, đó là cách tôi giải quyết một vấn đề tương tự trong sandbox của tôi, hy vọng nó sẽ giúp:

public class MyType 
{ 
    public virtual ISingleResult<int> ReturnSomeResult() { throw new NotImplementedException(); } 
} 

[TestMethod] 
public void TestMethod1() 
{ 
    var mockMyType = new Mock<MyType>(); 
    var mockSingleResult = new Mock<ISingleResult<int>>(); 
    IEnumerable<int> someEnumerable = new int[] {1,2,3,4,5}; 
    mockSingleResult.Setup(result => result.GetEnumerator()).Returns(someEnumerable.GetEnumerator()); 
    mockMyType.Setup(myType => myType.ReturnSomeResult()).Returns(mockSingleResult.Object); 

    Assert.AreEqual(15, mockMyType.Object.ReturnSomeResult().ToList().Sum()); 
} 
+0

Câu trả lời hay ... đây là những gì tôi sẽ làm. – womp

+1

Xin lỗi, tôi cảm thấy như một kẻ ngốc ở đây vì tôi không thể thấy cách tôi có thể giải quyết vấn đề của mình. Tôi thấy một cách tiếp cận tốt nhưng nó không giải quyết được những gì tôi cần. Tôi đã xem xét các video MVC Storefront của Rob Conery và tôi có thể thấy mẫu kho lưu trữ là những gì tôi cần nhưng điều đó không dễ dàng được triển khai với các bối cảnh dữ liệu LinqToSql như tôi có thể thấy. –

+0

Câu trả lời hay, đã giải quyết được vấn đề của tôi. – Odd

5

Tôi đã tạo một lớp đã triển khai ISingleResult và chỉ cần đặt một Danh sách trong đó. Tôi khá mới với loại mã hóa, vì vậy trong khi điều này làm việc cho tôi, sử dụng nguy cơ của riêng bạn (và nếu bạn thấy lỗ gửi bình luận).

class SingleResult<T>:ISingleResult<T> 
{ 
    readonly List<T> _list = new List<T>(); 

    public void Add(T item) 
    { 
     _list.Add(item); 
    } 

    #region Interface Items 

    public IEnumerator<T> GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public object ReturnValue { get { return _list; } } 

    public void Dispose() { } 

    #endregion 
} 

Điều này sau đó có thể được sử dụng để trả lại một phần của mô hình. Đây là cách tôi sử dụng nó với Rhino Mocks:

[TestMethod] 
public void TestSomething() 
{ 
    //Arrange 
    // Make a data context and DAL 
    var _ctx = MockRepository.GenerateMock<IDataClassesDataContext>(); 
    var someDALClass = new SomeDALClass(_ctx); 

    User testUser = UserObjectHelper.TestUser(); 
    SingleResult<User> userList = new SingleResult<User> { testUser }; 

    // Indicate that we expect a call the to sproc GetUserByUserID 
    _ctx.Expect(x => x.GetUserByUserID(testUser.UserID)).Return(userList); 

    //Act 
    someDALClass.UpdateUser(testUser); 

    //Assert 
    Assert.IsTrue(SomeTestCondition()); 
} 
+0

Rất tốt, +1. Tôi đang sử dụng lớp này với một vài thay đổi: 1. '_list' là một' IEnumerable 'thay vì' Danh sách '. 2. Tôi vượt qua một bộ sưu tập sẵn sàng để sử dụng trong constructor lớp thay vì có một phương thức 'Add'. – Konamiman

Các vấn đề liên quan