问题
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
回答1:
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.
来源:https://stackoverflow.com/questions/3114948/how-to-setup-a-simple-unit-test-with-moq