Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using MOQ to verify expression parameter

I am trying to verify the method i am tested has been invoked with a particular expression. I have spent hours on this without the result i wanted.

This is the System under test

public class sut
{
    private IEntityUtil _ew;
    public sut(IEntityUtil ew)
    {
        _ew = ew;
    }

    public void Search()
    {
        Guid id = Guid.Parse("CB594050-3845-4EAF-ABC5-34840063E94F");
        var res = _ew.SelectSingle<Post>(w => w.Id == id, new PersonalSiteEntities());
    }

}

This is the dependency

public interface IEntityUtil
{
    TEntity SelectSingle<TEntity>(Expression<Func<TEntity, bool>> predicate, System.Data.Objects.ObjectContext ctx)
        where TEntity : EntityObject;
    List<TEntity> SelectList<TEntity>(Expression<Func<TEntity, bool>> predicate, System.Data.Objects.ObjectContext ctx)
        where TEntity : EntityObject;
    bool Insert<TEntity>(TEntity entity, System.Data.Objects.ObjectContext ctx)
        where TEntity : EntityObject;
}

And this is how i am trying to test it

  public class tst
{
    [TestMethod]
    public void tst1()
    {
        var cwMock = new Mock<ConsoleApplication1.IEntityUtil>();

        Guid id = Guid.Parse("CB594050-3845-4EAF-ABC5-34840063E94F");

        //cwMock.Setup(x => x.SelectSingle<ConsoleApplication1.Post>(w => w.Id == id, It.IsAny<System.Data.Objects.ObjectContext>())).Returns(new ConsoleApplication1.Post()).Verifiable();


        //cwMock.Setup(x => x.SelectSingle(It.IsAny<Expression<Func<ConsoleApplication1.Post, bool>>>(), It.IsAny<System.Data.Objects.ObjectContext>())).Returns(new ConsoleApplication1.Post()).Verifiable();


        Expression<Func<ConsoleApplication1.Post, bool>> func = (param) => param.Id == id;

        cwMock.Setup(x => x.SelectSingle<ConsoleApplication1.Post>(func, It.IsAny<System.Data.Objects.ObjectContext>())).Returns(new ConsoleApplication1.Post());

        var sut = new ConsoleApplication1.sut(cwMock.Object);

        sut.Search();

        //cwMock.VerifyAll();

        cwMock.Verify(x => x.SelectSingle(func, It.IsAny<System.Data.Objects.ObjectContext>()));
    }


}

Please note the second commented setup will make the test pass but it wont let me verify that a specific expression has been passed in.

Thanks in advance.

like image 597
user2278921 Avatar asked Nov 12 '22 07:11

user2278921


1 Answers

Two things that will greatly help (us help you) are

  1. Give your test a meaningful name so we know what you're after,
  2. Arrange your test into three areas, and separate by comments or whitespace:

    • Arrange,
    • Act,
    • Assert

This makes it a bit more clear what the action is.

That said, it appears to me that you are trying to assert that ew.SelectSingle was called once when calling sut.Search()?

Also I noticed you're creating the Guid in your test but never doing anything with it. So, here is a quick proposal on your test (not using the IDE so you may find errors):

    [Fact]
    public void Verify_SelectSingle_IsCalledOnce( ){

        Guid id = Guid.Parse( "CB594050-3845-4EAF-ABC5-34840063E94F" );
        var cwMock = new Mock<ConsoleApplication1.IEntityUtil>( );
        var post = new ConsoleApplication1.Post{ Id = id };
        cwMock
          .Setup( x=> x.SelectSingle<ConsoleApplication1.Post>(It.IsAny<Guid> ))
          .Returns( post );
        var sut = new ConsoleApplication1.sut(cwMock.Object);



        sut.Search();



        cwMock.Verify( 
          x=> x.SelectSingle( It.IsAny<ObjectContect>( o => o.Id == id )), 
          Times.Once);
    }
like image 138
Damon Avatar answered Nov 15 '22 06:11

Damon