Moq object not working when executing a secondary command

user3805235

Hi I am attempting to write a unit test for a class CommandBusiness:

public class CommandBusiness
{
    IRepository<Command> _repository;

    public CommandBusiness(IRepository<Command> repository)
    {
        _repository = repository;
    }

    public List<Command> GetCommandsFromProjectId(int id)
    {
        return _repository.SearchFor(command => command.ProjectId == id);
    }

    public List<Command> GetAll()
    {
        return _repository.GetAll();
    }

    public void Delete(int id)
    {
        Entities.Command command = _repository.GetById(id);

        _repository.Delete(command);
    }
}

public interface IRepository<T> where T : new()
{
    void Delete(T entity);
    List<T> SearchFor(Expression<Func<T, bool>> predicate);
    List<T> GetAll();
    T GetById(int id);
}

public class OrmLiteRepository<T> : IRepository<T> where T : new()
{
    public IDbConnectionFactory DbFactory { get; private set; }
    string ConnectionString = "";
    public OrmLiteRepository()
    {
        DbFactory = null; // OrmLiteConnectionFactory(ConfigurationManager.AppSettings["ConnectionString"].ToString(), SqlServerDialect.Provider);
    }

    public List<T> SearchFor(Expression<Func<T, bool>> predicate)
    {
        using (IDbConnection db = DbFactory.OpenDbConnection())
        {
            return db.Select(predicate);
        }
    }
    public List <T> GetAll()
    {
        using (IDbConnection db = DbFactory.OpenDbConnection())
        {
            return db.Select<T>();
        }
    }

    public void Delete(T entity)
    {
        using (IDbConnection db = DbFactory.OpenDbConnection())
        {
            db.Delete<T>(entity);
        }
    }

    public T GetById(int Id)
    {
        using (IDbConnection db = DbFactory.OpenDbConnection())
        {
            return db.GetById<T>(Id);
        }
    }
}

public class Command 
{
    public int Id { get; set; }

    public string CommandText
    {
        get;
        set;
    }
    public bool AppendToNextLine
    {
        get;
        set;
    }
    public int ProjectId
    {
        get;
        set;
    }
    public int SortOrder
    {
        get;
        set;
    }
}

public class Testing
{
    [TestMethod]
    public void TestMethod()
    {
        List<Command> commandsx = new List<Command>
        {
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 1, ProjectId = 1 , SortOrder = 1},
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 2, ProjectId = 1 , SortOrder = 2},
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 3, ProjectId = 2 , SortOrder = 3},
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 4, ProjectId = 2 , SortOrder = 4},
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 5, ProjectId = 3 , SortOrder = 5},
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 6, ProjectId = 3 , SortOrder = 6},
            new Command { AppendToNextLine = false, CommandText = "SomeText", Id = 7, ProjectId = 3 , SortOrder = 7}
        };

        Mock<IRepository<Command>> mockProductRepository = new Mock<IRepository<Command>>();

        mockProductRepository.Setup(mPR => mPR.GetAll()).Returns(commandsx);

        var comBusiness = new CommandBusiness(mockProductRepository.Object);

        var comsoriginal = comBusiness.GetAll();  

        comBusiness.Delete(3);
        comsoriginal = comBusiness.GetAll();
    }
}

When I attempt to run the above code I get comsoriginal out as holding 7 items, next I execute the delete command and then requery the comBusiness.GetAll and again I get a count of 7, I would have expected a count of 6. Any thoughts????

Sam Holder

you code for CommandBusiness.GetAll() does this:

public List<Command> GetAll()
{
    return _repository.GetAll();
}

you create a mock for your repository which does return a fixed list:

Mock<IRepository<Command>> mockProductRepository = new Mock<IRepository<Command>>();

mockProductRepository.Setup(mPR => mPR.GetAll()).Returns(commandsx);

regardless of how many times you call CommandBusiness.GetAll() you will always get back the fixed list. that is what mocks do.

In actuality what you want to test for your CommandBusiness is not that the number of entities returned is correct, but only that it interacts with its dependecies (in this case the IRepository) correctly. The CommandBusiness unit does not have the responsibility for deleting the Commands, it delegates this command to the IRepository. Assuming that the repository does its job of deleting correctly the only functionality of this class is to call the correct method on the IRepository. So for a true unit test you should create a mock IRepository and set an expectation that Delete with the value 3 will be called, then call Delete with a value 3 on your CommandBusiness and verify that the expected call does indeed happen.

IMHO these tests do not provide significant value as the are really testing the implementation of CommandBusiness and not the behavior. These tests are brittle and will need to change every time the implementation changes.

I would prefer a test which actually interacts with the repository (like the one you have written) (even if that is slower) as this tests the behaviour, regardless of how it is implemented.

You could create a test which tests the combination of your CommandBusiness and IRepository by creating a TestRepository class which just wraps a simple collection. then you could use your existing test, but pass your TestRepository in instead of your current mock IRepository and then your test should pass, as the CommandBusiness will have an actual repository which will be being affected by the Delete method as well as the GetAll method.

Alternatively don't have a mock or a TestRepository, just use the real OrmLightRepository and spin up a new DB for the test. This will validate that everything actually works in the real situation.

The best of all worlds would be to make the repository configurable in the tests. Most of the time use a standard in memory collection for your respository. This will mean your tests are fast. But you can't be sure that you didn't use some linq command which won't be supported by the actual DB, so on the CI server use config to switch the tests to a real DB and verify that things will actually work in real life.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

bash array working in command prompt but not working when executing as ksh

From Dev

Executing command for sendmail not working

From Dev

Executing shell command not working in AWS

From Dev

Executing shell command not working in AWS

From Dev

Executing system command in scala not working

From Dev

Error when executing tcpdump command

From Dev

MemoryError, when executing a working code

From Dev

Working cmd command not executing correctly when called via cmd.exe /C

From Dev

sed command not working while executing C file

From Dev

Executing command using Paramiko exec_command on device is not working

From Dev

How to retain quotes when executing a command in bash

From Dev

RuntimeException when executing SubRequest in command line

From Dev

Stop terminal auto executing when pasting a command

From Dev

How to hide terminal output when executing a command?

From Dev

PSEXEC Not executing command when password with " is specified

From Dev

Paramiko Issues - Channel Closed when Executing a Command

From Dev

Mongodump - command not found when executing dump

From Dev

IllegalArgumentException when executing command with ProcessBuilder in Java

From Dev

Stop terminal auto executing when pasting a command

From Dev

How to hide terminal output when executing a command?

From Dev

RuntimeException when executing SubRequest in command line

From Dev

string error when executing sql command

From Dev

error when executing find command using variable

From Dev

Command window when executing a project with sqlite amalgamation

From Dev

Paramiko Issues - Channel Closed when Executing a Command

From Dev

simplessh library hangs when executing a command

From Dev

MongoDB indexes not working when executing $elemMatch

From Dev

Why does patsubst stop working when using secondary expansion of $$*?

From Dev

$.when promise object not working

Related Related

  1. 1

    bash array working in command prompt but not working when executing as ksh

  2. 2

    Executing command for sendmail not working

  3. 3

    Executing shell command not working in AWS

  4. 4

    Executing shell command not working in AWS

  5. 5

    Executing system command in scala not working

  6. 6

    Error when executing tcpdump command

  7. 7

    MemoryError, when executing a working code

  8. 8

    Working cmd command not executing correctly when called via cmd.exe /C

  9. 9

    sed command not working while executing C file

  10. 10

    Executing command using Paramiko exec_command on device is not working

  11. 11

    How to retain quotes when executing a command in bash

  12. 12

    RuntimeException when executing SubRequest in command line

  13. 13

    Stop terminal auto executing when pasting a command

  14. 14

    How to hide terminal output when executing a command?

  15. 15

    PSEXEC Not executing command when password with " is specified

  16. 16

    Paramiko Issues - Channel Closed when Executing a Command

  17. 17

    Mongodump - command not found when executing dump

  18. 18

    IllegalArgumentException when executing command with ProcessBuilder in Java

  19. 19

    Stop terminal auto executing when pasting a command

  20. 20

    How to hide terminal output when executing a command?

  21. 21

    RuntimeException when executing SubRequest in command line

  22. 22

    string error when executing sql command

  23. 23

    error when executing find command using variable

  24. 24

    Command window when executing a project with sqlite amalgamation

  25. 25

    Paramiko Issues - Channel Closed when Executing a Command

  26. 26

    simplessh library hangs when executing a command

  27. 27

    MongoDB indexes not working when executing $elemMatch

  28. 28

    Why does patsubst stop working when using secondary expansion of $$*?

  29. 29

    $.when promise object not working

HotTag

Archive