public void GetContent_ThrowsArgumentNullExceptionIfSourceIsNull() { // Arrange ContentRetrieverService testSubject = CreateContentRetrieverService(); // Act and assert Assert.Throws <ArgumentNullException>(() => testSubject.GetContent(null)); }
public void GetContent_RetrievesContentOnlyOnceAndCachesContentInMemory() { // Arrange var dummySource = new Uri("C:/dummySource"); var dummyContent = new ReadOnlyCollection <string>(new string[0]); const string dummyCacheDirectory = "dummyCacheDirectory"; var dummyCancellationToken = new CancellationToken(); Mock <ContentRetrieverService> mockTestSubject = CreateMockContentRetrieverService(); mockTestSubject.CallBase = true; mockTestSubject.Setup(t => t.GetContentCore(dummySource, dummyCacheDirectory, dummyCancellationToken)). Callback(() => Thread.Sleep(200)). // Arbitrary sleep duration Returns(dummyContent); // Mock<T>.Object isn't thread safe, if multiple threads call it at the same time, multiple instances are instantiated - https://github.com/moq/moq4/blob/9ca16446b9bbfbe12a78b5f8cad8afaa755c13dc/src/Moq/Mock.Generic.cs#L316 // If multiple instances are instantiated, multiple _cache instances are created and GetContentCore gets called multiple times. ContentRetrieverService testSubject = mockTestSubject.Object; // Act var threads = new List <Thread>(); var results = new ConcurrentBag <ReadOnlyCollection <string> >(); for (int i = 0; i < 3; i++) // Arbitrary number of threads { var thread = new Thread(() => results.Add(testSubject.GetContent(dummySource, dummyCacheDirectory, dummyCancellationToken))); thread.Start(); threads.Add(thread); } foreach (Thread thread in threads) { thread.Join(); } // Assert mockTestSubject.Verify(t => t.GetContent(dummySource, dummyCacheDirectory, dummyCancellationToken), Times.Exactly(3)); mockTestSubject.Verify(t => t.GetContentCore(dummySource, dummyCacheDirectory, dummyCancellationToken), Times.Once); // Lazy should prevent GetContentCore from being called multiple times ReadOnlyCollection <string>[] resultsArr = results.ToArray(); Assert.Equal(3, resultsArr.Length); Assert.Same(resultsArr[0], dummyContent); Assert.Same(resultsArr[0], resultsArr[1]); // Result should get cached after first call Assert.Same(resultsArr[1], resultsArr[2]); // Same relation is transitive }