How to use Moq to mock and test an IService
I have a service set up as follows:
public interface IMyService
{
void AddCountry(string countryName);
}
public class MyService : IMyService
{
public void AddCountry(string countryName)
{
/* Code here that access repository and checks if country exists or not.
If exist, throw error or just execute. */
}
}
Test.cs
[TestFixture]
public cla开发者_StackOverflow社区ss MyServiceTest
{
[Test]
public void Country_Can_Be_Added()
{ }
[Test]
public void Duplicate_Country_Can_Not_Be_Added()
{ }
}
How do I test AddCountry
and moq the repository or service. I'm really not sure what to do here or what to mock. Can someone help me out?
Frameworks I'm using:
- NUnit
- Moq
- ASP.NET MVC
And why would you need to use moq? You don't need to mock IService. In your case you can write your test like this:
[Test]
public void Country_Can_Be_Added()
{
new MyService().AddCountry("xy");
}
[Test]
public void Duplicate_Country_Can_Not_Be_Added()
{
Assert.Throws<ArgumentException>(() => new MyService().AddCountry("yx"));
}
You would need to mock the IRepository if you had a scenario like this:
interface IRepository { bool CanAdd(string country); }
class MyService : IService
{
private IRepository _service; private List<string> _countries;
public IEnumerable<string> Countries { get { return _countries; } }
public X(IRepository service) { _service = service; _countries = new List<string>(); }
void AddCountry(string x)
{
if(_service.CanAdd(x)) {
_conntires.Add(x);
}
}
}
And a test like this:
[Test]
public void Expect_AddCountryCall()
{
var canTadd = "USA";
var canAdd = "Canadd-a";
// mock setup
var mock = new Mock<IRepository>();
mock.Setup(x => x.CanAdd(canTadd)).Returns(false);
mock.Setup(x => x.CanAdd(canAdd)).Returns(true);
var x = new X(mock.Object);
// check state of x
x.AddCountry(canTadd);
Assert.AreEqual(0, x.Countires.Count);
x.AddCountry(canAdd);
Assert.AreEqual(0, x.Countires.Count);
Assert.AreEqual(0, x.Countires.Count);
Assert.AreEqual(canAdd, x.Countires.First());
// check if the repository methods were called
mock.Verify(x => x.CanAdd(canTadd));
mock.Verify(x => x.CanAdd(canAdd));
}
You test the concrete MyService. If it takes a dependency (say on IRepository) you would create a mock of that interface and inject it into the service. As written, no mocks are needed to test the service.
The point of creating the IMyService interface is to test other classes that depend on MyService in isolation. Once you know Repository works, you don't need to test it when you're testing MyService (you mock or stub it out). Once you know MyService works, you don't need to test it when you're testing MySomethingThatDependsOnMyService.
精彩评论