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
Hi, I want to make sure that the item returned from a list is always the same item, may I know how to do this? I don't where at which index I access the list, as long as i am getting an item from the list, I should always get the same item.
________
hot penny stocks
asked by nsoonhui (59.1k points)

3 Answers

0 votes
If you wrap the list in members on the class you're testing, it's pretty simple - just set up mocks against those members. If it's a public field, you have a larger problem because you can't mock types from mscorlib. If that's the case, you won't be able to have just any arbitrary index return your expected value, but you can set up an expected list and "poke" it into the class being tested.

I just posted a blog article on this with some examples showing both "wrapping" the list and exposing a public field. Hopefully that will help answer the question. If not, maybe post some example code here so we can see what you're trying to do.
answered by tillig (6.7k points)
0 votes
If you wrap the list in members on the class you're testing, it's pretty simple - just set up mocks against those members. If it's a public field, you have a larger problem because you can't mock types from mscorlib. If that's the case, you won't be able to have just any arbitrary index return your expected value, but you can set up an expected list and "poke" it into the class being tested.

I just posted a blog article on this with some examples showing both "wrapping" the list and exposing a public field. Hopefully that will help answer the question. If not, maybe post some example code here so we can see what you're trying to do.


Thanks for the code! But I have one small issue, let say I want to make sure that the item at i ( i being unknown at test writing time) always return "expected", anyway to do this?

Take for example, I modify your test FieldListMocks() to something like this:

        [Test]
        public void FieldListMocks()
        {
            // Here the challenge is that there aren't any
            // members on the ListExample object that wrap
            // the list so we've actually got to "mock" the
            // list proper.

            // To accomplish the mock, we'll modify the object's
            // state by poking in our expected field value.
            ListExample example = new ListExample();
            ObjectState state = new ObjectState(example);
            List<string> expectedList = new List<string>();
            expectedList.Add("expected");
            state.SetField("PublicList", expectedList);

            // Now when we ask for the list, we're getting the
            // expected list, not the original member.
          int publicIndex = 10; //can be any number
            Assert.AreEqual("expected", example.PublicList[0]);
          Assert.AreEqual("expected", example.PublicList[publicIndex]);

            // When we're done, we can reset things back to the
            // original values, which means the real PublicList
            // will be back - and will still be empty.
            state.ResetState();
            Assert.IsEmpty(example.PublicList);
        }


How to make it pass?
________
Norseman
answered by nsoonhui (59.1k points)
0 votes
Unfortunately, as mentioned in the article, you can't mock mscorlib types, which includes List<T>. That means either:
  • You need to write a wrapper around the list and not access the list directly, OR
  • You're not going to be able to return a known value for any arbitrary location in the list.

More directly, since it doesn't look like you're wrapping the list - you're accessing it directly - you're not going to be able to do what you want to do.

I suppose another alternative would be to create a dummy list of sufficiently large size such that any index in the range you could ask for will actually have a corresponding element in the dummy list and use the ObjectState mocking mechanism.

Which is to say:

[Test] 
public void FieldListMocks() 
{
  // Figure out what the largest possible index
  // is that your test will ask for. You won't be able
  // to use Int32.MaxValue, though, because you'll run
  // out of memory.
  int largestPossibleIndex = 1000;

  ListExample example = new ListExample(); 
  ObjectState state = new ObjectState(example); 
  List<string> expectedList = new List<string>(largestPossibleIndex);

  // Fill the dummy list with values. It'll actually
  // have to have the value IN the list, though,
  // because you can't mock List<T>.
  for(int i = 0; i < largestPossibleIndex; i++)
  {
    expectedList.Add("expected"); 
  }

  // Do the mocking. We still have a restriction that
  // publicIndex is less than largestPossibleIndex.
  state.SetField("PublicList", expectedList); 
  int publicIndex = 10; //can be any number 
  Assert.AreEqual("expected", example.PublicList[0]); 
  Assert.AreEqual("expected", example.PublicList[publicIndex]); 

  // When we're done, we can reset things back to the 
  // original values, which means the real PublicList 
  // will be back - and will still be empty. 
  state.ResetState(); 
  Assert.IsEmpty(example.PublicList); 
} 


I don't think I'd actually go down that route, though. Seems a little heavy-handed. Instead, I'd look at either wrapping the list or re-examining the test to see if I really need to test that a list returns a specific value for literally ANY index. Might be that the test can be changed such that it still tests the code but doesn't require you to mock every arbitrary index anyone could ask for.
answered by tillig (6.7k points)
...