2012-08-31 49 views
5

Tôi có một bài kiểm tra đơn vị để xác minh rằng một đối tượng (nói Foo) sẽ gọi phương thức nhất định (giả sử Bar) khi một sự kiện được kích hoạt với một số sự kiện nhất định. Để thử phương pháp nói, tôi sử dụng ảo và còn sơ khai các Foo lớpLàm thế nào để buộc moq gọi cho nhà xây dựng?

Mock<Foo> stubbedFoo = new Mock<Foo>(mockEventProvider); 

mockEventProvider.Raise(x => x.MyEvent += null, myEventArgs) //fire the event 
stubbedFoo.Verify(foo => foo.Bar()); verify Bar is called as a result 

Tuy nhiên, thất bại trên, Bar sẽ không được gọi, rõ ràng bởi vì đối tượng Foo không phải là sự kiện xây dựng. Tuy nhiên, nếu tôi thêm một dòng như sau:

Mock<Foo> stubbedFoo = new Mock<Foo>(mockEventProvider); 
var workAround = stubbedFoo.Object //adding this workaround will work 
mockEventProvider.Raise(x => x.MyEvent += null, myEventArgs) //fire the event 
stubbedFoo.Verify(foo => foo.Bar()); verify Bar is called as a result 

Nó sẽ hoạt động, bởi vì gọi điện đang bật. Có một giải pháp thanh lịch hơn so với thêm dòng này?

Trả lời

1

Tôi không nghĩ bạn có thể. Tôi đã kiểm tra các moq source và chọc qua nó và nó không giống như các intercepter proxy từ castle thực sự được tạo ra cho đến khi bạn gọi .Object. Nhìn vào dấu vết này:

public object Object 
{ 
    get { return this.GetObject(); } 
} 

private object GetObject() 
{ 
    var value = this.OnGetObject(); 
    this.isInitialized = true; 
    return value; 
} 

Tiếp theo là

protected override object OnGetObject() 
{ 
    if (this.instance == null) 
    { 
     this.InitializeInstance(); 
    } 

    return this.instance; 
} 

nào thực hiện điều này:

private void InitializeInstance() 
{ 
    PexProtector.Invoke(() => 
    { 
     this.instance = proxyFactory.CreateProxy<T>(
      this.Interceptor, 
      this.ImplementedInterfaces.ToArray(), 
      this.constructorArguments); 
    }); 
} 

ProxyFactory thực sự tạo ra các đối tượng và kết thúc tốt đẹp nó trong một proxy

public T CreateProxy<T>(ICallInterceptor interceptor, Type[] interfaces, object[] arguments) 
{ 
    var mockType = typeof(T); 

    if (mockType.IsInterface) 
    { 
     return (T)generator.CreateInterfaceProxyWithoutTarget(mockType, interfaces, new Interceptor(interceptor)); 
    } 

    try 
    { 
     return (T)generator.CreateClassProxy(mockType, interfaces, new ProxyGenerationOptions(), arguments, new Interceptor(interceptor)); 
    } 
    catch (TypeLoadException e) 
    { 
     throw new ArgumentException(Resources.InvalidMockClass, e); 
    } 
    catch (MissingMethodException e) 
    { 
     throw new ArgumentException(Resources.ConstructorNotFound, e); 
    } 
} 
+0

tôi thấy .. bạn có nghĩ rằng đây là một lỗ hổng trong moq? –

+0

Tôi muốn nói đây có lẽ là một quyết định có chủ ý, nhưng moq là nguồn mở để bạn có thể thay đổi nó nếu bạn muốn – devshorts

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