I have an action method like this in my controller
public ActionResult Index()
{
using (NorthwindDataContext db = new NorthwindDatacontext())
{
var results = db.GetRecordSets(arg1, ....).ToList();
// use results as list
}
return View();
}
and I wanted to start making tests for it (yes, after it was built, not before... but the code was written before I started to use TDD so... )
and I figured out that adding a property such as this one to the controller
public delegate NorthwindDatacontext ContextBuilderDelegate();
public ContextBuilderDelegate ContextBuilder { get; set; }
I could add in the constructor something like this...
ContextBuilder = () => new NorthwindDatacontext();
then I could test the ActionMethod setting the ContextBuilder property with a mock of NorthwindDatacontext
var controller = new MyController();
var mockDataContext = new Mock<NorthwindDatacontext>();
controller.ContextBuilder = () => mockDataContext.Object;
But... I found no way to use this because all methods of NorthwindDatacontext use ISingleResult as returnType and I cant find the way to create an object with that interface. I've tried this
var theResult = new List<GetRecordSetsResult>();
// fill the data structure here with the provided result...
mockDataContext.Setup(c => c. GetRecordSets()).Returns(theResult as
ISingleResult<GetRecordSetsResult>);
but it doesn't work because theResult is null when converted to ISingleResult.
Is there any way to create a ISingleResult object to test this way or I'm doing the incorrect way to do things here?
Thanks in Advance
ToList()
is an extension method for IEnumerable, which is easy to mock, because it only has one member method -- GetEnumerator()
.
Still you might have problems mocking NorthwindDataContext class, if its methods are not virtual...
Anyways, that's how I solved a similar problem in my sandbox, hope it helps:
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());
}
I created a class that implemented ISingleResult and just put a List in it. I am fairly new to this type of coding, so while this worked for me, use at your own risk (and if you see holes post a comment).
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
}
This can then be used to return in part of a mock. This is how I ended up using it with 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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With