2015-02-24 23 views
7

Tôi muốn thực hiện phương pháp mở rộng giả, nhưng nó không hoạt động. Điều này có thể giải quyết như thế nào?Phương pháp mở rộng giả lập NSubstitute

public static class RandomExtensions 
{ 
    public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive) 
    { 
     // ... 
    } 
} 

[Fact] 
public void Select() 
{ 
    var randomizer = Substitute.For<DefaultRandom>(); 
    randomizer.NextInt32s(3, 1, 10).Returns(new int[] { 1, 2, 3 }); 
} 
+2

AFAIK bạn không thể giả lập phương pháp mở rộng với khung mocking miễn phí. Bởi vì các phương thức mở rộng chỉ là các phương thức tĩnh và bạn không thể giả lập một phương thức tĩnh với các khuôn khổ mocking miễn phí. TypeMock làm điều này tôi nghĩ (nhưng đó là vượt ra ngoài câu hỏi). –

Trả lời

3

NSubstitute không thể giả lập phương pháp mở rộng theo nhận xét của Sriram, nhưng bạn vẫn có thể chuyển đối số được giả mạo sang một phương thức mở rộng.

Trong trường hợp này, lớp Random có phương pháp ảo, vì vậy chúng tôi có thể giả lập trực tiếp với NSubstitute và các công cụ mô phỏng dựa trên DynamicProxy khác. (Đối với NSubstitute nói riêng chúng ta cần phải có những lớp mocking rất cẩn thận. Xin vui lòng đọc các cảnh báo trong the documentation.)

public static class RandomExtensions { 
    public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive) { /* ... */ } 
} 
public class RandomExtensionsTests { 
    [Test] 
    public void Select() 
    { 
     const int min = 0, max = 10; 
     var randomizer = Substitute.For<Random>(); 
     randomizer.Next(min, max).Returns(1, 2, 3); 

     var result = randomizer.NextInt32s(3, 0, 10).ToArray(); 

     Assert.AreEqual(new[] {1, 2, 3}, result); 
    } 
} 
+0

Tôi đã thử điều này nhưng giả lập không trả lại {1,2,3} nhưng đi vào mã/* ... * /. Xem [gist] (https://gist.github.com/anonymous/a27d3bd572d8abdaf4770805b93eefdb) – Damian

+0

@Damian Nó chỉ hoạt động nếu phương thức mở rộng gọi đối tượng được mô phỏng. Trong gist, 'NextInt32s()' sẽ cần phải gọi 'random.Next (minInclusive, maxInclusive)'. –

+0

Trong khung dotnet Random.Next (min, max) trả về một int, không phải là một mảng int. Cảnh báo mới cho C#! – Damian

-1

Theo RẮN đảo ngược sự phụ thuộc nguyên tắc xác định rằng mô hình cấp thấp hơn không nên phụ thuộc mô hình cao cấp nhưng phụ thuộc vào trừu tượng như giao diện và chế giễu khái niệm được sử dụng chủ yếu để giao diện giả để mức thấp mô hình không được kiểm tra.

+0

Có, nhưng nếu tôi định nghĩa giao diện cho DefaultRandom và giả lập nó, thì nó không thấy phương thức mở rộng NextInt32s. Làm thế nào tôi có thể làm được? – user3526923

0

Có bạn có thể thử nếu bạn tạo một giao diện như IRandom và mở rộng giao diện thay vì thực hiện thực tế . Sau đó, bạn sẽ có thể giả lập giao diện trong lớp thử nghiệm của bạn.

public interface IRandom 
{ 
} 

public class Random : IRandom 
{  
} 

public static class RandomExtensions 
{ 
    public static string NextInt32s(
     this IRandom random, 
     int neededValuesNumber, 
     int minInclusive, 
     int maxExclusive) 
    { 
    } 
} 

Trong thử nghiệm lớp add bạn:

IRandom randomizer = Substitute.For<IRandom>(); 
var result = randomizer.NextInt32s(3,0,10); 

Bởi quá trình này bạn chỉ là chế giễu giao diện không phải là lớp thực tế.

Các vấn đề liên quan