我一直想弄清楚我是如何进行单元测试服务的,到目前为止还没有。
我正在使用xUnit和NSubstitute(由朋友建议),下面是我想要运行的简单测试(当前失败)。
public class UnitTest1
{
private readonly RallyService _rallyService;
public UnitTest1(RallyService rallyService)
{
_rallyService= rallyService;
}
[Fact]
public void Test1()
{
var result = _rallyService.GetAllRallies();
Assert.Equal(2, result.Count());
}
}
我的拉力赛服务类只是简单地调用数据库来获取所有Rally entites并返回它们:
public class RallyService : IRallyService
{
private readonly RallyDbContext _context;
public RallyService(RallyDbContext context)
{
_context = context;
}
public IEnumerable<Rally> GetAllRallies()
{
return _context.Rallies;
}
}
任何指导都将不胜感激。
答案 0 :(得分:2)
由于您使用的是.NET Core,我假设您还使用了Entity Framework Core。尽管可以模拟先前EF版本中的大多数操作,但EF Core建议使用in-memory database进行单元测试。即您不需要模拟RallyDbContext
,因此此特定测试不需要NSubstitute
。在使用该服务测试控制器或应用程序时,您需要NSubstitute
来模拟服务。
以下是使用内存数据库编写的Test1
。
public class UnitTest1
{
private readonly DbContextOptions<RallyDbContext> _options;
public UnitTest1()
{
// Use GUID for in-memory DB names to prevent any possible name conflicts
_options = new DbContextOptionsBuilder<RallyDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
}
[Fact]
public async Task Test1()
{
using (var context = new RallyDbContext(_options))
{
//Given 2 records in database
await context.AddRangeAsync(new Rally { Name = "rally1" }, new Rally { Name = "rally2" });
await context.SaveChangesAsync();
}
using (var context = new RallyDbContext(_options))
{
//When retrieve all rally records from the database
var service = new RallyService(context);
var rallies = service.GetAllRallies();
//Then records count should be 2
Assert.Equal(2, rallies.Count());
}
}
}
使用此单元测试的工作测试应用程序在我的GitHub中供您参考。我在实际应用程序中使用了SQL Express。
答案 1 :(得分:0)
我认为使用带参数的单元测试构造函数是标准的。单元测试运行器将新增这个类,除非你使用的东西将自动注入该参数,我认为测试将无法运行。
这是一个标准的夹具布局:
public class SampleFixture {
[Fact]
public void SampleShouldWork() {
// Arrange stuff we need for the test. This may involved configuring
// some dependencies, and also creating the subject we are testing.
var realOrSubstitutedDependency = new FakeDependency();
realOrSubstitutedDependency.WorkingItemCount = 42;
var subject = new Subject(realOrSubstitutedDependency);
// Act: perform the operation we are testing
var result = subject.DoWork();
// Assert: check the subject's operation worked as expected
Assert.Equal(42, result);
}
[Fact]
public void AnotherTest() { /* ... */ }
}
如果您需要在测试之间进行通用设置,则可以使用无参数构造函数并在那里进行常规初始化。
就您要测试的特定课程而言,您需要确保您的RallyDbContext
处于已知状态,以便可重复且可靠地进行测试。您可能希望查找特定于测试实体框架的答案以获取更多信息。