如何使用 Moq 来模拟和测试 IService

发布于 2024-10-08 03:39:55 字数 741 浏览 1 评论 0原文

我的服务设置如下:

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 class MyServiceTest
{
    [Test]
    public void Country_Can_Be_Added()
    { }

    [Test]
    public void Duplicate_Country_Can_Not_Be_Added()
    { }

}

如何测试 AddCountry 并最小起订量存储库或服务。我真的不知道在这里做什么或嘲笑什么。有人可以帮我吗?

我正在使用的框架:

  1. NUnit
  2. Moq
  3. ASP.NET MVC

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 class 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:

  1. NUnit
  2. Moq
  3. ASP.NET MVC

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

少女净妖师 2024-10-15 03:39:55

为什么需要使用最小起订量?您不需要模拟 IService。在您的情况下,您可以像这样编写测试:

[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"));
}

如果您有这样的场景,则需要模拟 IRepository:

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);
     }
  }      
}

和这样的测试:

[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));
}   

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));
}   
末蓝 2024-10-15 03:39:55

您测试具体的 MyService。如果它需要依赖项(比如 IRepository),您将创建该接口的模拟并将其注入到服务中。正如所写,不需要模拟来测试服务。

创建 IMyService 接口的目的是隔离测试依赖于 MyService 的其他类。一旦您知道 Repository 可以工作,您就不需要在测试 MyService 时测试它(您可以模拟或存根它)。一旦您知道 MyService 可以工作,您在测试 MySomethingThatDependsOnMyService 时就不需要测试它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文