chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Currently I'm using following pattern:

        public class MockedObj
        {
            public void DoIt(object o)
            {
                   ....
            }

            ....

        }


        private class Stub
        {
            public object Param { get; set; }

            public void DoIt(object o)
            {
                Param = o;
            }
        }


        [Test]
        [Isolated]
        public void Test()
        {
            MockedObj obj = Isolate.Fake.Instance<MockedObj>();
            Stub stub = new Stub();
            Isolate.Swap.CallsOn(obj).WithCallsTo(stub);
            obj.DoIt(new object());
            Assert.IsNotNull(stub.Param);
        }



May be I missed smth in documentation... Is there more straight forward way to achieve the same.
asked by knst (2.9k points)

6 Answers

0 votes
Hi knst,

You are using the method redirection pattern (we call it duck-type swapping internally), which is a valid way to solve many testing scenarios but a bit verbose. Most scenarios can be solved with the simpler mechanisms provided by Isolate.WhenCalled().

What are you trying to test in the code you posted? What you seem to be verifying is that the code you redirected to is working properly, i.e. verifying that Isolator is doing its job when redirecting... What would you like to verify in the code under test?

Doron
Typemock Support
answered by doron (17.2k points)
0 votes
I'm testing DAO and capturing DbCommand instance it uses to push data to DB (DB is mocked). Scenario I need is
- Create business object
- Call DAO.Insert(bo)
- Catch SqlCommand instance and check that it's params are correctly populated
- Prevent call to DB.
answered by knst (2.9k points)
0 votes
hi

have you tried using the Verify.WasCalledWithExactArguments()?

something in the spirit of:
object param = new object();
obj.DoIt(param)
Isolate.Verify.WasCalledWithExactArguments(()=>obj.DoIt(param));
answered by error (6.6k points)
0 votes
Looks like I failed to explain what i need.
The SqlCommand is initilized in private code of DAO, I need to check that it is populated with correct params and CommandText.
I do not like to add any public methods to DAO returning SqlCommand as it is required only in tests (Internal method and InternalsVisibleTo also not very good option ).
It would be nice to not only mock method, but also be able to execute Assert against it's params.

WasCalledWithExactArguments compares passed arguments with provided instances, while i need to get the instance of provided argument and explore it and there is no way to provide the value for it to be compared with.
answered by knst (2.9k points)
0 votes
Hi,

lets see if i understood you correctly.
Is this more or less what you are doing?
public class BusinessObject
{
    public int CustomerID {get;set;}
    public string CompanyName { get; set; }
}

public class DAO
{
    public static void Insert(BusinessObject data)
    {
        using (SqlConnection connection = new SqlConnection("Some connection string"))
        {
            connection.Open();

            string queryString = String.Format("INSERT INTO Customers (CustomerID, CompanyName) Values('{0}', '{1}')",
                data.CustomerID,data.CompanyName);

            SqlCommand command = new SqlCommand(queryString, connection);
            command.ExecuteNonQuery();
        }

    }
}


if this is the case then heres a way to check that the proper string is passed to the SqlCommand ctor.
(I would have done it in the AAA syntax but I'm not sure they have the ability to verify arguments on the constructor)
[TestMethod]
[VerifyMocks]
public void DaoExample()
{
    string ExpectedSQLString = "INSERT INTO Customers" + 
        " (CustomerID, CompanyName) Values('6', 'yahoo')";
    using (RecordExpectations rec = new RecordExpectations())
    {
        using (SqlConnection connection = new SqlConnection("Some connection string"))
        {
            connection.Open();

            SqlCommand fake = new SqlCommand("", null);
            rec.CheckArguments(ExpectedSQLString, Check.IsAny());
            fake.ExecuteNonQuery();
            rec.Return(6);
        }
    }


    BusinessObject data = new BusinessObject();
    data.CustomerID = 6;
    data.CompanyName = "yahoo";

    DAO.Insert(data);
}
answered by error (6.6k points)
0 votes
close but not exact :) you are testing the arguments of SqlCommand constructor. While I need to validate the SqlCommand object that DAO passes to DB (parameters , timeout, commandText etc).
In the sample i provided in my first post it is achieved (I'm using EntLib and mocking DataBase.ExecuteNonQuery method intercepting the DbCommand instance passed to it as param).
I was looking for some short way to achieve the same. Looks like it does not exist.
Anyway thanks for your help :)
answered by knst (2.9k points)
...