How to UnitTest a Function in a mocked method

一个人想着一个人 提交于 2019-12-12 04:56:35

问题


How can I test the DeleteAppointmentById here?

 Func<IDataAdapterRW, IEnumerable<uint>> function = db =>   DeleteAppointmentById(db, appointmentId);

 return _dataContextProvider.GetContextRW().Run(function);

_dataContextProvider is mocked with moq. If I run the test it never enters DeleteAppointmentById of course

The method to test:

public IEnumerable<uint> DeleteAppointment(uint appointmentId)
    {
        Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
        return _dataContextProvider.GetContextRW().Run(function);
    }

DeleteAppointmentById is the inner method (private) I am really interested in.

my test:

[Test]
    public void DeleteAppointment_Valid_DeletedRecordId()
    {
        //Setup
        var dbContextMock = new Mock<IDataContextProvider>();
        var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();

        dbContextMock.Setup(d => d.GetContextRW())
            .Returns(dataAdapterMock.Object);

        dataAdapterMock.Setup(a => a.Run(It.IsAny<Action<IDataAdapterRW>>()));
        var calendarService = new CalendarService(dbContextMock.Object);

        //Run
        var result = calendarService.DeleteAppointment(1);

        //Assert
        Assert.AreEqual(1, result);
    }

回答1:


You can access the result of the Func passed as parameter in Run method, and to Assert the result like below.

Why to return the result? Because it's a mock and don't know how Run method is behaving.

[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
    //Setup
    var dbContextMock = new Mock<IDataContextProvider>();
    var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();

    dbContextMock.Setup(d => d.GetContextRW())
        .Returns(dataAdapterMock.Object);

    dataAdapterMock.Setup(a => a.Run(It.IsAny<Func<IDataAdapterRW, IEnumerable<uint>>>()))
                   .Returns((Func<IDataAdapterRW, IEnumerable<uint>> func) => { return func(dataAdapterMock.Object);}); // configure the mock to return the list
    var calendarService = new CalendarService(dbContextMock.Object);

    //Run
    int id = 1;
    var result = calendarService.DeleteAppointment(id);

    //Assert
    var isInList = result.Contains(id); // verify the result if contains the
    Assert.AreEqual(isInList, true);
}



回答2:


Unit tests tend to take the following structure:

  • Arrange: set up the context. In this case, you'd probably create an appointment and save it to the database.

  • Act: call the unit you're testing. In this case, DeleteAppointmentById(db, appointment).

  • Assert: check if side effects and returns were correct. In this case, you may attempt to load this appointment from the database, and assert that you were unable (because it should have been deleted).



来源:https://stackoverflow.com/questions/29670372/how-to-test-a-method-with-an-action-delegate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!