Tôi đang cố gắng tạo kho lưu trữ giả để kiểm tra đơn vị với đối tượng lớp có quan hệ một đến nhiều. Tôi đang sử dụng ASP.NET MVC và LINQ to SQL. Tài liệu tham khảo của tôi là cuốn sách "Pro ASP.NET MVC Framework" của Steven Sanderson.Cách tạo kho lưu trữ giả với liên kết 1 đến nhiều cho MVC
tôi đã tạo ra các lớp học với các hiệp hội Entity:
[Table(Name = "Albums")]
public class Album
{
[Column(IsDbGenerated = true, IsPrimaryKey = true)]
public int AlbumID { get; set; }
[Column]
public string Title { get; set; }
private EntitySet<Track> _tracks;
[Association(Storage = "_tracks", ThisKey = "AlbumID", OtherKey = "AlbumID")]
public EntitySet<Track> Tracks
{
get { return _tracks; }
set { _tracks.Assign(value); }
}
}
[Table(Name = "Tracks")]
public class Track
{
[Column(IsPrimaryKey = true)]
public int TrackID { get; set; }
[Column]
public string Title { get; set; }
[Column]
public int AlbumID { get; set; }
}
Và một giao diện trừu tượng cho kho:
public interface IMusicRepository
{
IQueryable<Album> Albums { get; }
IQueryable<Track> Tracks { get; }
}
tôi đã có thể tạo ra một kho lưu trữ giả cho Album - FakeMusicRepository:
public class FakeMusicRepository : IMusicRepository
{
private static IEnumerable<Track> fakeTracks = new List<Track>
{
new Track {AlbumID = 1, TrackID = 1, Title = "Flood"},
new Track {AlbumID = 1, TrackID = 2, Title = "Liquid"},
new Track {AlbumID = 2, TrackID = 1, Title = "Song 1"},
new Track {AlbumID = 2, TrackID = 2, Title = "Song 2"}
}.AsEnumerable();
private static IQueryable<Album> fakeAlbums = new List<Album>
{
new Album {AlbumID = 1, Title = "Jars of Clay"},
new Album {AlbumID = 2, Title = "Wind in the Wheat"}
}.AsQueryable();
public IQueryable<Album> Albums
{
get { return fakeAlbums; }
}
public IQueryable<Track> Tracks
{
get { return fakeTracks.AsQueryable(); }
}
}
Chỉ hoạt động tốt miễn là tôi không cố gắng truy cập bất kỳ tuyến đường nào. Nói cách khác, Album.Title hoạt động nhưng truy cập vào Album.Tracks.Count() sẽ tạo ra một ngoại lệ tham chiếu null. Tôi đã không chắc chắn nếu Linq-To-SQL hoặc LINQ-To-Objects sẽ đón Hiệp hội và sử dụng nó tự động với các đối tượng giả hay không.
Vấn đề là dù tôi cố gắng làm gì và dường như không thể chỉ định lớp Tracks cho Album. Tôi biết rằng EntitySet được dựa trên IEnumerable nhưng nó là một thách thức để đúc danh sách Enumerable vào một EntitySet.
Album được mong đợi một EntitySet nhưng cách duy nhất tôi đã có thể vượt qua trong đó là thông qua một helper tùy chỉnh:
public static class EntityCollectionHelper
{
public static EntitySet<T> ToEntitySet<T>(this IEnumerable<T> source) where T : class
{
EntitySet<T> set = new EntitySet<T>();
set.AddRange(source);
return set;
}
}
Đây là càng gần như tôi đã đến:
public class FakeMusicRepository2 : IMusicRepository
{
private static IEnumerable<Track> fakeTracks = new List<Track>
{
new Track {AlbumID = 1, TrackID = 1, Title = "Flood"},
new Track {AlbumID = 1, TrackID = 2, Title = "Liquid"},
new Track {AlbumID = 2, TrackID = 1, Title = "Song 1"},
new Track {AlbumID = 2, TrackID = 2, Title = "Song 2"}
}.AsEnumerable();
private static EntitySet<Track> Tracks1 = (from t in fakeTracks where t.AlbumID == 1 select t).ToEntitySet();
private static EntitySet<Track> Tracks2 = (from t in fakeTracks where t.AlbumID == 2 select t).ToEntitySet();
private static IQueryable<Album> fakeAlbums = new List<Album>
{
new Album {AlbumID = 1, Title = "Jars of Clay", Tracks=Tracks1},
new Album {AlbumID = 2, Title = "Wind in the Wheat", Tracks=Tracks2}
}.AsQueryable();
public IQueryable<Album> Albums
{
get { return fakeAlbums; }
}
public IQueryable<Track> Tracks
{
get { return fakeTracks.AsQueryable(); }
}
}
Tuy nhiên, khi tôi cố gắng truy cập Album.Tracks tôi nhận được
System.NullReferenceException: Tham chiếu đối tượng không được đặt thành phiên bản của o bject.
Đây là thử nghiệm implamentation/đơn vị:
[Test]
public void Test_FakeMusicRepository()
{
// Arrange: Setup Repository
var dc = new FakeMusicRepository2();
// Act:
var albums = dc.Albums.AsQueryable();
// Load the first test location
Album album = dc.Albums.First();
// Assert: That there are records in the Album Object
Assert.Greater(albums.Count(), 0, "No Albums Records Returned!");
//Assert that our first Album is not Null
Assert.IsNotNull(album, "returned Album is Null!");
// Assert: That we have the correct Album
Assert.AreEqual(album.AlbumID, 1, "Returned Album ID is not correct!");
// Try to Count the related sub table (Tracks)
var trackCount = album.Tracks.Count();
// Try to get the first Track
var track1 = album.Tracks.FirstOrDefault();
// Assert: The Album has Tracks
Assert.Greater(trackCount, 0, "Album has no Tracks");
// Assert: That First track is not Null
Assert.IsNotNull(track1, "Track1 object was Null!");
// Assert: That Track1 has data
Assert.IsNotNull(track1.TrackID, "Track1's ID was Null!");
}
Tôi đã trải qua những ngày tìm kiếm một câu trả lời cho câu hỏi này và đã không tìm thấy bất kỳ ví dụ vì vậy nếu một người nào đó sẽ có thể gửi một lao động ví dụ trả lời Tôi chắc rằng những người khác cũng sẽ thích.
Tôi rất mới với MVC và kiểm tra đơn vị vì vậy hãy dễ dàng với tôi. Tôi có IoC và Moq trên tay là tốt nhưng tôi biết thậm chí ít hơn về những điều này nhưng tôi đang lập kế hoạch sử dụng cả hai với dự án này. Nếu có một cách tốt hơn để làm điều này thì tôi là tất cả tai! Cảm ơn.
Bạn có mã mà bạn đang sử dụng để truy cập tuyến đường không? I E. mã triển khai của bạn? Điều đó có thể giúp gỡ lỗi. Nếu bạn đang làm Album.Tracks.Count() thì lý do có thể là bạn không chỉ định đúng bài hát, nhưng nó phụ thuộc vào mã thực hiện. – Odd
Ý tưởng hay - Tôi đã đăng mã thử nghiệm/triển khai đơn vị của mình. – ColinICN