简体   繁体   中英

Error when attempting to run my XUnit Tests

I wrote a few tests in XUnit to test my data access layer. I instantiated my DAL objects & configs the same way I would if I were using it in the actual web application(this is configured to run against a dev environment for testing purposes), however XUnit throws an error:

Message: The following constructor parameters did not have matching fixture data: IConfiguration config, IMediaDataAccess media

I'm a bit new to XUnit, so unsure what the problem is. Normally ASP.NET would inject instances of IConfiguration and IMediaDataAccess for me, but that doesn't seem to be the case here.

My Test class & a sample test case:

    public class DataAccessLayerTests
    {
        public IConfiguration Config { get; set; }
        private IMediaDataAccess mediaData;

        public IMediaDataAccess MediaData { get => mediaData; set => mediaData = value; }

        public DataAccessLayerTests(IConfiguration config, IMediaDataAccess media)
        {
            this.MediaData = media;
            this.Config = config;
        }

        public void GetAllMediaAsync_MediaListIsReturned()
        {


            List<Media> testData = mediaData.GetAllMedia().Result;


            Assert.IsType<List<Media>>(testData);

        }

}

The test(s) all fail due to the following error: Message: The following constructor parameters did not have matching fixture data: IConfiguration config, IMediaDataAccess media

For anyone else having this problem, Alexey's comment is correct. You need to download a mocking framework (like Moq) and use it to mock up the dependencies your code is expecting. For example, below is one of my fixed unit tests:

public void IndexDataModel_ShouldDisplayMedia()
{

    var mockLogger = new Mock<ILogger<IndexModel>>();
    var mockDataAccess = new Mock<IMediaDataAccess>();
    mockDataAccess.Setup(media => media.GetAllMedia()).ReturnsAsync(GetTestMedia());
    IndexModel indexController = new IndexModel(mockDataAccess.Object, mockLogger.Object);


    var result = indexController.OnGet();
    var viewResult = Assert.IsType<PageResult>(result);
    var model = Assert.IsAssignableFrom<IEnumerable<Media>>(
        indexController.mediaList);

}

The trick is you need to mock up anything that you normally depend on getting injected into your constructor, in my case this was:

var mockLogger = new Mock<ILogger<IndexModel>>();
var mockDataAccess = new Mock<IMediaDataAccess>();

My constructor takes both an ILogger and an IMediaDataAccess, so I needed to mock those. Additionally, the other code is there to provide dummy return values when your mocked dependencies are used by the test. This is done with the .Setup line of code. All this does(I think) is when GetAllMedia() is called, the mock object returns the contents of GetTestMedia() instead of needing to make the actual calls. Just make sure whatever function you write has the same return type as the real function. For reference, this is my GetTestMedia() function:

    private List<Media> GetTestMedia()
    {
        var listMedia = new List<Media>();
        Media testMedia = new Media
        {
            Description = "TestDesc",
            Genre = "TestGenre",
            Name = "TestName",
            Rating = MediaRating.Excellent,
            Type = MediaType.Movie,
            Id = 1
        };

        listMedia.Add(testMedia);

        Media testMedia2 = new Media
        {
            Description = "TestDesc2",
            Genre = "TestGenre2",
            Name = "TestName2",
            Rating = MediaRating.Poor,
            Type = MediaType.Music,
            Id = 2
        };

        listMedia.Add(testMedia2);

        return listMedia;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM