Parameter values not passed into method of mocked object

3 posts, 0 answers
  1. Simon
    Simon avatar
    2 posts
    Member since:
    Jun 2013

    Posted 24 Jun 2013 Link to this post

    I've set up a mocked object with a couple of arranged methods. How do I pass in parameters to exercise the arranged methods?
    When i call target.GetValue with 5/Aug/2012, the GetData method receives the value of 1/Jan/1983 in its startDate parameter. What do i need to do in order for the arranged methods to receive the required parameter value?

    ------- set up mocking ------------
                var dataAccess = Mock.Create<IDataAccess>();
                Mock.Arrange(() => dataAccess.DataExists(Arg.IsAny<SiteLocation>(), Arg.Matches<DateTime>(d => d >= startDate), Arg.Matches<DateTime>(d => d <= endDate))).Returns(true);
                Mock.Arrange(() => dataAccess.RetrieveData(Arg.IsAny<SiteLocation>(), Arg.Matches<DateTime>(d => d >= startDate), Arg.Matches<DateTime>(d => d <= endDate))).Returns(data);
                DataLoader target = new DataLoader(dataAccess);

                // act
                int actual;
                actual = target.GetValue(location, date)[0];

    -------------------- called method on non-mocked object ---------------
            public List<int> GetValue(SiteLocation location, DateTime date)
            {
                var data = new List<int>();

                var temp = GetData(location, date, DateTime.Now);
                if (temp.Count > 0)
                {
                    // todo: if there are gaps in the data fill with -999
                    data = temp.Select(t => t.Value).ToList();
                }
                else { }

                return data;
            }

    ------------------------ called method on mocked object ------------------
            public List<DataRecord> GetData(SiteLocation location, DateTime startDate, DateTime endDate)
            {
                var data = new List<DataRecord>();

                if (dataAccess.DataExists(location, startDate, endDate))
                {
                    data = dataAccess.RetrieveData(location, startDate, endDate);
                }else{}

                return data;
            }
  2. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 24 Jun 2013 Link to this post

    Hello Simon,

    Thank you for contacting our support central with such a detailed message.

    For the purpose of testing, I managed write the missing parts like this:
    public class DataLoader
    {
        public IDataAccess dataAccess;
     
        public DataLoader(IDataAccess dataA)
        {
            this.dataAccess = dataA;
        }
     
        public List<int> GetValue(SiteLocation location, DateTime date)
        {
            var data = new List<int>();
     
            var temp = GetData(location, date, DateTime.Now);
            if (temp.Count > 0)
            {
                // todo: if there are gaps in the data fill with -999
                data = temp.Select(t => t.Value).ToList();
            }
            else { }
     
            return data;
        }
     
        public List<DataRecord> GetData(SiteLocation location, DateTime startDate, DateTime endDate)
        {
            var data = new List<DataRecord>();
     
            if (dataAccess.DataExists(location, startDate, endDate))
            {
                data = dataAccess.RetrieveData(location, startDate, endDate);
            }
            else { }
     
            return data;
        }
    }
     
    public interface IDataAccess
    {
        bool DataExists(SiteLocation location, DateTime startDate, DateTime endDate);
     
        List<DataRecord> RetrieveData(SiteLocation location, DateTime startDate, DateTime endDate);
    }
     
    public class DataRecord
    {
        public int Value;
    }
     
    public class SiteLocation
    {
         
    }

    Having the above, I finished your test method the following way:
    [TestMethod]
    public void GetValue_ShouldReturnFakeCollectionMember()
    {
        List<DataRecord> data = new List<DataRecord>()
        {
            new DataRecord() {Value = 1},
            new DataRecord() {Value = 2},
        };
        SiteLocation location = new SiteLocation();
        DateTime date = new DateTime(2012, 8, 5); // 5/Aug/2012
        DateTime startDate = new DateTime(2011, 8, 5); // 5/Aug/2012 - Start date should be <= than "date"
        DateTime endDate = new DateTime(2014, 8, 5); // 5/Aug/2014 - End date should be >= than DateTime.Now
     
        // Arrange
        var dataAccess = Mock.Create<IDataAccess>();
     
        Mock.Arrange(() => dataAccess.DataExists(Arg.IsAny<SiteLocation>(),
                                Arg.Matches<DateTime>(d => d >= startDate),
                                Arg.Matches<DateTime>(d => d <= endDate)))
                        .Returns(true);
        Mock.Arrange(() =>  dataAccess.RetrieveData(Arg.IsAny<SiteLocation>(),
                                Arg.Matches<DateTime>(d => d >= startDate),
                                Arg.Matches<DateTime>(d => d <= endDate)))
                        .Returns(data);
     
        // Act
        DataLoader target = new DataLoader(dataAccess);
     
        int actual;
        actual = target.GetValue(location, date)[0];
     
        // Assert
        Assert.AreEqual(1, actual);
    }
    I haven`t changed your arrangements and the test passes as expected. The only thing I needed to take into consideration is that, inside the GetValue() method, you are calling DetData() with DateTime.Now for endDate argument. This means, you will need to pass a future time as an argument expectation for the endDate as well.

    I hope this helps. Please, do not hesitate to contact us further if there are more issues.

    Regards,
    Kaloyan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  3. DevCraft R3 2016 release webinar banner
  4. Simon
    Simon avatar
    2 posts
    Member since:
    Jun 2013

    Posted 27 Jun 2013 Link to this post

    Thanks,

    I've adjusted the arrangements so they no longer check the endDate as the exact endDate value used is not known at this point.

    Mock.Arrange(() => dataAccess.DataExists(Arg.IsAny<SiteLocation>(), Arg.Matches<DateTime>(d => d >= startDate), Arg.IsAny<DateTime>())).Returns(true);
    Mock.Arrange(() => dataAccess.RetrieveData(Arg.IsAny<SiteLocation>(), Arg.Matches<DateTime>(d => d >= startDate), Arg.IsAny<DateTime>())).Returns(data);
                var target = new SunDataLoader(dataAccess);

    The 1/Jan/1983 value came from another piece of code and was nothing to do with the mocking.
Back to Top