我如何使用Mock C#测试我的Service类中的特定方法?

时间:2016-09-29 17:26:58

标签: c# unit-testing

请帮我解决我的问题。我有一个Service类,如下所示:

public class RateService:IRatesService
{
    ...
    public RatesDTO GetById(int Id)
    {
        return Mapper.Map<Rates, RatesDTO>(this.db.Rates.GetAll().Where(m => m.RateId == Id).First());
    }
}

接口IRatesServicelooks就像代码样本:

public interface IRatesService
{
    .....
    RatesDTO GetById(int Id);
    ....
}

现在我尝试测试公共RatesDTO GetById(int Id)方法。我的代码如下:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Mock<IRatesService> mock = new Mock<IRatesService>();
        mock.Setup(m => m.GetById(It.IsAny<int>())).Returns<RatesDTO>(total=>total);

        Assert.IsNotNull(mock.Object.GetById(1));
    }
}

但是当我运行测试时,我得到一个像这样的错误:

  

测试名称:TestMethod1测试
  FullName:Provider.Tests.Services.UnitTest1.TestMethod1

     

结果讯息:

     

测试方法Provider.Tests.Services.UnitTest1.TestMethod1扔了   异常:System.ArgumentException:Невозможнопреобразоватьобъект   типа“System.Int32”ктипу“Provider.BLL.DTO.RatesDTO”。

测试服务类和方法的最佳做法是什么?

2 个答案:

答案 0 :(得分:0)

您正在尝试测试您的模拟。这没有任何意义。

您应该努力测试您的实际代码。 在您的情况下,您可能希望确保GetById返回具有正确id值的RatesDTO。

您可以使用Mock框架,以方便您的测试。 例如如果您正在尝试执行单元测试而您正在使用数据库层,则可能需要模拟数据库层GetAll函数并返回多个对象,然后运行测试以检查您是否实际返回了正确的对象(相同的ID)。

答案 1 :(得分:0)

您的RateService是受测试的系统。为单元测试创​​建模拟时,规范是模拟被测系统的依赖关系。

因此,鉴于您当前的服务,我们可以说它依赖于数据存储。

public class RateService : IRatesService {
    private readonly IDbContext db;
    public RateService(IDbContext dbContext) {
        this.db = dbContext;
    }
    //...
    public RatesDTO GetById(int Id) {
        return Mapper.Map<Rates, RatesDTO>(this.db.Rates.GetAll().Where(m => m.RateId == Id).First());
    }
    //...
}

IDbContext将是被测系统的依赖关系。

在测试RateService

时,你会嘲笑它
[TestClass]
public class RateServiceUnitTests {
    [TestMethod]
    public void Given_ValidId_GetById_Should_Return_Dto() {
        //Arrange
        var validId = 1;
        var fakes = new List<Rates>() {
            new Rates { RateId = validId }
        };
        var mock = new Mock<IDbContext>();
        //Assuming IDbContext.Rates.GetAll() returns an IEnumerable<Rates>
        mock.Setup(m => m.Rates.GetAll()).Returns(fakes);
        var sut = new RateService(mock.Object);
        //Act
        var result = sut.GetById(validId);
        //Assert
        Assert.IsNotNull(result);
    }
}

注意到您也在使用映射器。您应该确保为测试配置,否则测试将失败。在类中使用静态调用时,当您尝试隔离系统进行测试时,可能会导致问题。尝试将mapper添加为依赖项。