简体   繁体   English

如何从单元测试中消除对数据库的依赖

[英]How to eliminate the dependency on the database from a unit test

Is it possible to create a unit test for this method? 是否可以为此方法创建单元测试?

public void CheckIndicatorMeasurementRecordingValidity(IndicatorMeasurementRecording indicatorMeasurementRecording)
{
   var isDateRangeOverLapping = this.db.IndicatorMeasurementRecordingRepository.Any(r => r.IndicatorId == indicatorMeasurementRecording.Indicator.Id && r.Id != indicatorMeasurementRecording.Id
                && r.RecordingDateRange.ToDateTime >= indicatorMeasurementRecording.RecordingDateRange.FromDateTime
                && r.RecordingDateRange.FromDateTime <= indicatorMeasurementRecording.RecordingDateRange.ToDateTime);

   if (isDateRangeOverLapping)
   {
       throw new GrcUserException(IndicatorThresholdValidityManagementLocal.DateRangeOverlapping);
   }
}

I tried to create the test like this 我试图像这样创建测试

[TestMethod]
public void Indicator_measurement_date_range_overlapping_shall_throw_exception()
{
    var indicator = new Indicator();
    var oldIndicatorMeasurementRecording = new IndicatorMeasurementRecording();
    var newIndicatorMeasurementRecording = new IndicatorMeasurementRecording();
    var errorMessage = string.Empty;

    oldIndicatorMeasurementRecording.Id = 1;
    oldIndicatorMeasurementRecording.RecordingDateRange.FromDateTime = DateTime.Today.AddDays(-5);
    oldIndicatorMeasurementRecording.RecordingDateRange.ToDateTime = DateTime.Today;
    indicator.IndicatorMeasurementRecordings.Add(oldIndicatorMeasurementRecording);

    oldIndicatorMeasurementRecording.Id = 2;
    newIndicatorMeasurementRecording.RecordingDateRange.FromDateTime = DateTime.Today.AddDays(-2);
    newIndicatorMeasurementRecording.RecordingDateRange.ToDateTime = DateTime.Today;
    newIndicatorMeasurementRecording.Indicator = indicator;

    try
    {
        this.indicatorValidityProxy.CheckIndicatorMeasurementRecordingValidity(newIndicatorMeasurementRecording);
    }
    catch (Exception ex)
    {
        errorMessage = ex.Message;
    }

    Assert.AreEqual(IndicatorThresholdValidityManagementLocal.DateRangeOverlapping, errorMessage);
}

The problem is, the test always fails because this.db.IndicatorMeasurementRecordingRepository.Count for test is always 0. For development purpose it always returns the correct number. 问题是,测试始终失败,因为此测试的this.db.IndicatorMeasurementRecordingRepository.Count始终为0。出于开发目的,它始终返回正确的数字。 Only in the test purpose is it 0. 仅出于测试目的,它为0。

Can anyone tell me why this.db.IndicatorMeasurementRecordingRepository.Count for test purpose is always 0? 谁能告诉我为什么出于测试目的this.db.IndicatorMeasurementRecordingRepository.Count始终为0? And what is the best practice for writing the test for my case? 为我的案例编写测试的最佳实践是什么?

I'm not sure what the.db is, but assuming public class MyContext : DbContext and this.db is of type MyContext then with Mock you can: 我不确定the.db是什么,但是假设public class MyContext : DbContextthis.dbMyContext类型,那么使用Mock可以:

var contextMock = new Mock<MyContext>();
// arrange more

Essentially you would configure the contextMock to return a known set of your objects ( IndicatorMeasurementRecording ?) when the IndicatorMeasurementRecordingRepository is queried. 本质上,您将配置contextMock以在查询IndicatorMeasurementRecordingRepository时返回一组已知的对象( IndicatorMeasurementRecording ?)。 Something like: 就像是:

var dbSetMock = new Mock<IDbSet<DbEntity>>();
dbSetMock.Setup(m => m.Provider).Returns(data.Provider);
dbSetMock.Setup(m => m.Expression).Returns(data.Expression);
dbSetMock.Setup(m => m.ElementType).Returns(data.ElementType);
dbSetMock.Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

var contextMock = new Mock<MyContext>();
contextMock 
    .Setup(x => x.DbEntities)
    .Returns(dbSetMock.Object);

Where data would be a list of your objects to be returned from the mock. 数据将是要从模拟返回的对象列表。

Some links / examples to help you: 一些链接/示例可以帮助您:

I can't recreate your test case as there is too much code not there, but if you provide a mcve I am more than happy to look at the test in more detail. 我不能重新创建您的测试用例,因为那里没有太多的代码,但是如果您提供mcve,我很乐意更详细地查看测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为依赖于其他服务或数据库的服务编写单元测试 - How to write unit test for service having dependency on other service or database 如何对依赖于 Console 的 switch 语句进行单元测试 - How to unit test a switch statement with a dependency on Console 如何在单元测试中模拟依赖注入对象 - How to mock the dependency injection object in unit test 如何单元测试数据库类 - How to unit test Database Class 在单元测试中按context.Database.ExecuteSqlCommand类型模拟方法依赖项 - Mocking method dependency by type of context.Database.ExecuteSqlCommand in the unit test 从数据库获取数据的单元测试方法 - Unit Test method that gets data from database 如何从Test Automation中的源代码中删除用户名和密码? - How to eliminate usernames and passwords from source code in Test Automation? 如何在单元测试中创建 sqlite 数据库并在 class 完成所有测试后将其删除 C# .net - How to create sqlite database in unit test and remove it after all test from class done C# .net 如何在没有SitecoreContext依赖项注入的情况下对GlassController动作进行单元测试 - How to Unit Test a GlassController Action without SitecoreContext Dependency Injection 如何使用伪造对象的依赖关系对静态方法进行单元测试? - How to unit test a static method using a fake object for the dependency?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM