views:

37

answers:

1

I'm new to Moq and not quite sure why this won't run.

Repository Interface

using System.Collections.Generic;

public interface IRepository
{
    IEnumerable<string> list();
}

Service Interface

using System.Collections.Generic;

public interface IService
{
    IEnumerable<string> AllItems();
}

Service Class

using System.Collections.Generic;

public class Service : IService
{
    private IRepository _repository;

    public Service(IRepository repository)
    {
        this._repository = repository;
    }

    public IEnumerable<string> AllItems()
    {
        return _repository.list();
    }
}

Unit Test Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MoqTest;
using MoqTest.Controllers;
using Moq;
using MoqTest.Models;

[TestClass]
public class Tests
{
    private Mock<IRepository> _mockRepository;
    private IService _service;

    [TestMethod]
    public void my_test()
    {
        //Arrange.
        List<string> theList = new List<string>();
        theList.Add("test3");
        theList.Add("test1");
        theList.Add("test2");

        _mockRepository = new Mock<IRepository>();

        //The line below returns a null reference...
        _mockRepository.Setup(s => s.list()).Returns(theList);
        _service = new Service(_mockRepository.Object);

        //Act.
        var myList = _service.AllItems();
        Assert.IsNotNull(myList, "myList is null.");

        //Assert.
        Assert.AreEqual(3, myList.Count());
    }
}

I wanted to set this up as a very simple unit test. It is failing on the _mockRepository.Setup call. Any help would be appreciated!

EDIT -

Error Message

Test method Tests.my_test threw exception:  System.NullReferenceException: Object reference not set to an instance of an object..

Exception Stack Trace

Moq.MethodCall.SetFileInfo()
Moq.MethodCall..ctor(Mock mock, Expression originalExpression, MethodInfo method, Expression[] arguments)
Moq.MethodCallReturn..ctor(Mock mock, Expression originalExpression, MethodInfo method, Expression[] arguments)
ctor(Mock mock, Expression originalExpression, MethodInfo method, Expression[] arguments)
b__11()
Moq.PexProtector.Invoke[T](Func`1 function)
TResult](Mock mock, Expression`1 expression)
Setup[TResult](Expression`1 expression)
Tests.my_test() in C:\Users\xxx\Documents\Visual Studio 2008\Projects\MoqTest\MoqTest.Tests\Controllers\Tests.cs: line 28
+2  A: 

Unrelated to the problem you are having, you can move the mock initialization out into a common TestInitialize method that would get run before every test. This way you can keep the common init code in one place and make your tests much smaller and more readable.

[TestInitialize]
public void TestInit() {
    //Arrange.
    List<string> theList = new List<string>();
    theList.Add("test3");
    theList.Add("test1");
    theList.Add("test2");

    _mockRepository = new Mock<IRepository>();

    //The line below returns a null reference...
    _mockRepository.Setup(s => s.list()).Returns(theList);
    _service = new Service(_mockRepository.Object);
}

[TestMethod]
public void my_test()
{
    //Act.
    var myList = _service.AllItems();
    Assert.IsNotNull(myList, "myList is null.");

    //Assert.
    Assert.AreEqual(3, myList.Count());
}

I've just run this test exactly as posted and it worked for me. I am using Moq v4.0 beta There was a specific bug fix in this release that I needed, otherwise 3.1.4(the latest stable release) has been rock solid for me.

Igor Zevaka
Yep, that was my plan. I actually had it setup this way, but moved it all into the one test function to simplify before posting. (and make sure I wasn't calling something incorrectly)
Dragn1821
I just downloaded 3.1.416.3. Maybe I'll try 4.0 beta too...
Dragn1821
Upgrading to the beta worked! Thanks!
Dragn1821