asp.net 如何修复Xunit中的“以下构造函数参数没有匹配的fixture数据:Repository repo,IMapper mapper,ILogger logger”?

ut6juiuv  于 5个月前  发布在  .NET
关注(0)|答案(1)|浏览(68)

我正在使用Xunit为一个测试驱动开发的应用程序编写一些测试,但是由于某种原因,在我初始化构造函数的时候,服务器抛出了一个异常
以下构造函数参数没有匹配的fixture数据:Repository repo、IMapper mapper、ILogger logger
这是repository:

public class Repository 
{
    private IList<Subject> _subjects = new List<Subject>()
    {
        new Subject() 
            { 
                SubjectId = Guid.Parse("de331c36-6b31-4dd9-b50d-f677e51b987c"), 
                Title = "Math", 
                Credits = 8
            };       
    };

    public IEnumerable<Subject> GetAll() => _subjects;

    public Subject? GetById(Guid id) =>   
         _subjects.FirstOrDefault(x => x.SubjectId == id);

    public void Create(Subject subject) 
    {
        _subjects.Add(subject);
    }
}

字符串
这是控制器:

public class Controllers : ControllerBase
{
    private Repository _repo;
    private ILogger _logger;
    private IMapper _mapper;

    public Controllers(Repository repo, ILogger logger, IMapper mapper)
    {
        _repo = repo;
        _logger = logger; 
        _mapper = mapper;
    }

    public IActionResult CreateSubject(SubjectCreateDto subject)
    {
        if (subject == null)
        {
            _logger.LogError("Subject sent is null");
        }

        var subjectEntity = _mapper.Map<Subject>(subject);
        _repo.Create(subjectEntity);
       
       return Ok(subjectEntity);
    }
}


这些是测试:

public class UnitTest1: IClassFixture<Controllers>
{
    private Repository _repo;
    private IMapper _mapper;
    private ILogger _logger;

    public UnitTest1(Repository repo, IMapper mapper, ILogger logger) 
    {
        _repo = repo;
        _logger = logger;
        _mapper = mapper;
    }

    [Fact]
    public void CreateSubjectTest()
    {
        // Arrange
        var _subject = new Controllers(_repo, _logger, _mapper);
        var subject = new Subject()
        {
            SubjectId = Guid.Parse("22de7cb0-0453-4435-a219-3157bf3e3302"), 
            Title = "History", 
            Credits = 10,
        };

        // Act
        var subjectCreate = _mapper.Map<SubjectCreateDto>(subject);     
        var result = _subject.CreateSubject(subjectCreate) as ObjectResult;       
        
        // Assert
        Assert.NotNull(result);
        Assert.IsAssignableFrom<CreatedAtRouteResult>(result);
        Assert.Equal((int)HttpStatusCode.Created, result!.StatusCode);
    } 
}


我必须承认,我避免了对仓库使用mocking。在步骤中,我决定使用一个简单的IList来模拟对象。我不确定这是否与失败测试有关。
如果有人能帮我,我会很感激的。

hfsqlsce

hfsqlsce1#

单元测试构造函数不能有超过使用IClassFixture注入的参数。我想你误解了IClassFixture类的用途。IClassFixture负责创建一个类的示例,该类的构造函数中不需要参数,我将提供一个示例来帮助您理解使用IClassFixture时代码的外观但是,我建议在这种情况下不要使用IClassFixture;相反,我会在单元测试构造函数中创建控制器示例。
UnitTest1.cs

public class UnitTest1 : IClassFixture<ControllersFixture>
{
    private Controllers _controllers;

    public UnitTest1(ControllersFixture fixture)
    {
        _controllers = fixture.Controllers;
    }

    [Fact]
    public void CreateSubjectTest()
    {
        // Arrange
        var subject = new Subject()
        {
            SubjectId = Guid.Parse("22de7cb0-0453-4435-a219-3157bf3e3302"),
            Title = "History",
            Credits = 10,
        };

        // Act
        var subjectCreate = _controllers.Mapper.Map<SubjectCreateDto>(subject);
        var result = _controllers.CreateSubject(subjectCreate) as ObjectResult;

        // Assert
        Assert.NotNull(result);
        Assert.IsAssignableFrom<CreatedAtRouteResult>(result);
        Assert.Equal((int)HttpStatusCode.Created, result!.StatusCode);
    }
}

字符串
ControllersFixture.cs

public class ControllersFixture
{
    public Controllers Controllers { get; private set; }

    public ControllersFixture()
    {
        // You need to initialize your dependencies (repo, logger, mapper) here.
        var repo = new Repository(); // Initialize your repo with necessary data
        var logger = new YourLoggerImplementation(); // Initialize your logger
        var mapper = new YourMapperImplementation(); // Initialize your mapper

        Controllers = new Controllers(repo, logger, mapper);
    }
}


我建议你在这种情况下这样做(删除IClassFixture,你不需要它):
UnitTest1.cs

public class UnitTest1
{
    private Controllers _controllers;

    public UnitTest1()
    {
        // You need to initialize your dependencies (repo, logger, mapper) here.
        var repo = new Repository(); // Initialize your repo with necessary data
        var logger = new YourLoggerImplementation(); // Initialize your logger
        var mapper = new YourMapperImplementation(); // Initialize your mapper

        _controllers= new Controllers(repo, logger, mapper);
    }

    [Fact]
    public void CreateSubjectTest()
    {
        // Arrange
        var subject = new Subject()
        {
            SubjectId = Guid.Parse("22de7cb0-0453-4435-a219-3157bf3e3302"),
            Title = "History",
            Credits = 10,
        };

        // Act
        var subjectCreate = _controllers.Mapper.Map<SubjectCreateDto>(subject);
        var result = _controllers.CreateSubject(subjectCreate) as ObjectResult;

        // Assert
        Assert.NotNull(result);
        Assert.IsAssignableFrom<CreatedAtRouteResult>(result);
        Assert.Equal((int)HttpStatusCode.Created, result!.StatusCode);
    }
}


要在此控制器上初始化所需的服务,您可以执行以下操作:

public UnitTest1()
    {
        var repo = new Repository();
        var logger = new Mock<ILogger<Controllers>>();
        ServiceProvider serviceProvider = new ServiceCollection().AddAutoMapper(typeof(Program)).BuildServiceProvider();
        mapper = serviceProvider.GetRequiredService<IMapper>(); // Initialize your mapper with the proyect configuration, the typeof(Program) is the initial class of your proyect
    
        _controllers= new Controllers(repo, logger, mapper);
    }

相关问题