2

I am writing test code with xUnit and mock(moq) on C#.

However, the program through the interface cannot be executed.

The test code is as follows.

// test code
public void test1(string id, EntityA fd)
{
    var mockOrder = new Mock<InterfaceOrder>();
    var service = new ItemService(mockOrder.Object);
    var result = service.FunctionA(id, fd);
    Assert.False(result);
}
// service
public class ItemService(InterfaceOrder order)
{
    public bool FunctionA(string id, EntityA fd)
    {
        if (id == null) return false;
        // ↓ GetList() is not executed and does not return the expected list
        var list = order.GetList(id).ToList();
        return list.Count() > 0 ? true : false;
    }
}
// Interface Definition
public interface InterfaceOrder
{
    IEnumerable<SalesEntity> GetList(string id);
}
// Interface Facts
public class EntityFrameOrder : InterfaceOrder
{
    private readonly salesContext _context;
    public EntityFrameOrder(IOptions<ConnectionString> connection)
    {
        var connectionString = connection.Value.Path;
        DbContextOptionsBuilder<salesContext> opt = new();
        opt.UseOracle(connectionString);
        _context = new salesContext(opt.Options);
    }
    
    public IEnumerable<SalesEntity> GetList(string id)
    {
        var query = $@"
            SELECT *
              FROM SALES
            WHERE CUSTOMERCD = :id
        ";
        try
        {
            using DbManager dbManager = new();
            ~
            return list;
        }
    }
}

GetList() of FunctionA of ItemService is not executed and does not return the expected result.

I am using mock, but do we also need a mock instance of context?

If you have any tips to give me, please let me know.

Thank you.

7
  • @Dai Thank you.Title has been changed. Commented Nov 28, 2024 at 12:24
  • What does this have to do with EF? Except the smell that perhaps a CRUD class was wrapped over the Unit-of-Work that is DbContext. EntityFrameOrder has no business configuring a DbContext and the vendor-specific SQL shouldn't be used at all. context.Sales.First(s=>s.CustomerCD=someId) should be used instead. The DbContext should be configured outside the DbContext/data layer, whatever. Preferably in Program.cs, as all examples and tutorials show. This would allow EF to work with any database without the rest of the application noticing it Commented Nov 28, 2024 at 12:26
  • how do you examine GetList isn't executed? It's a mock, so unless you provide some implementation for that function in your mocks Setup, it won't do anything. Or in other words: your mocked object has nothing to do with your EntityFrameOrder-class, that's the entire purpose of a mock in the first place. Commented Nov 28, 2024 at 12:26
  • @MakePeaceGreatAgain Thank you. I think I am using mock for the wrong purpose. Is there any better way to do a GetList()? Commented Nov 28, 2024 at 12:34
  • What are you trying to test or abstract here? The Command/Order or the Unit-of-Work? If you want to mock the "Order", mock GetList itself and configure it to return a list of items. If you want to mock the UoW/DbContext, 1) don't and 2) configure the DbContext class to use either the in-memory provider or SQLite in memory mode. Commented Nov 28, 2024 at 12:34

1 Answer 1

0

The object that mockOrder.Object creates doesn't know how to behave when its members are invoked. You need to tell it, by using mockOrder.Setup, e.g.

[Fact]
public void Test2()
{
    var mockOrder = new Mock<InterfaceOrder>();
    mockOrder.Setup(o => o.GetList("foo")).Returns([new()]);
    var service = new ItemService(mockOrder.Object);

    var result = service.FunctionA("foo", new EntityA());

    Assert.True(result);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.